/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=2 sw=2 et tw=78: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. *//* * structures that represent things to be painted (ordered in z-order), * used during painting and hit testing */#ifndef NSDISPLAYLIST_H_#define NSDISPLAYLIST_H_#include"gfxContext.h"#include"mozilla/ArenaAllocator.h"#include"mozilla/Attributes.h"#include"mozilla/Array.h"#include"mozilla/DebugOnly.h"#include"mozilla/EnumSet.h"#include"mozilla/Maybe.h"#include"mozilla/TemplateLib.h" // mozilla::tl::Max#include"nsCOMPtr.h"#include"nsContainerFrame.h"#include"nsPoint.h"#include"nsRect.h"#include"nsRegion.h"#include"nsDisplayListInvalidation.h"#include"DisplayListClipState.h"#include"LayerState.h"#include"FrameMetrics.h"#include"mozilla/EnumeratedArray.h"#include"mozilla/Maybe.h"#include"mozilla/UniquePtr.h"#include"mozilla/TimeStamp.h"#include"mozilla/gfx/UserData.h"#include"mozilla/layers/LayerAttributes.h"#include"nsCSSRenderingBorders.h"#include<stdint.h>#include"nsTHashtable.h"#include<stdlib.h>#include<algorithm>classgfxContext;classnsIContent;classnsDisplayList;classnsDisplayTableItem;classnsISelection;classnsIScrollableFrame;classnsDisplayLayerEventRegions;classnsDisplayScrollInfoLayer;classnsCaret;namespacemozilla{classFrameLayerBuilder;namespacelayers{classLayer;classImageLayer;classImageContainer;classStackingContextHelper;classWebRenderCommand;classWebRenderParentCommand;classWebRenderDisplayItemLayer;}// namespace layersnamespacewr{classDisplayListBuilder;}// namespace wr}// namespace mozilla// A set of blend modes, that never includes OP_OVER (since it's// considered the default, rather than a specific blend mode).typedefmozilla::EnumSet<mozilla::gfx::CompositionOp>BlendModeSet;/* * An nsIFrame can have many different visual parts. For example an image frame * can have a background, border, and outline, the image itself, and a * translucent selection overlay. In general these parts can be drawn at * discontiguous z-levels; see CSS2.1 appendix E: * http://www.w3.org/TR/CSS21/zindex.html * * We construct a display list for a frame tree that contains one item * for each visual part. The display list is itself a tree since some items * are containers for other items; however, its structure does not match * the structure of its source frame tree. The display list items are sorted * by z-order. A display list can be used to paint the frames, to determine * which frame is the target of a mouse event, and to determine what areas * need to be repainted when scrolling. The display lists built for each task * may be different for efficiency; in particular some frames need special * display list items only for event handling, and do not create these items * when the display list will be used for painting (the common case). For * example, when painting we avoid creating nsDisplayBackground items for * frames that don't display a visible background, but for event handling * we need those backgrounds because they are not transparent to events. * * We could avoid constructing an explicit display list by traversing the * frame tree multiple times in clever ways. However, reifying the display list * reduces code complexity and reduces the number of times each frame must be * traversed to one, which seems to be good for performance. It also means * we can share code for painting, event handling and scroll analysis. * * Display lists are short-lived; content and frame trees cannot change * between a display list being created and destroyed. Display lists should * not be created during reflow because the frame tree may be in an * inconsistent state (e.g., a frame's stored overflow-area may not include * the bounds of all its children). However, it should be fine to create * a display list while a reflow is pending, before it starts. * * A display list covers the "extended" frame tree; the display list for a frame * tree containing FRAME/IFRAME elements can include frames from the subdocuments. * * Display item's coordinates are relative to their nearest reference frame ancestor. * Both the display root and any frame with a transform act as a reference frame * for their frame subtrees. */// All types are defined in nsDisplayItemTypes.h#define NS_DISPLAY_DECL_NAME(n, e) \ virtual const char* Name() override { return n; } \ virtual Type GetType() override { return e; }/** * Represents a frame that is considered to have (or will have) "animated geometry" * for itself and descendant frames. * * For example the scrolled frames of scrollframes which are actively being scrolled * fall into this category. Frames with certain CSS properties that are being animated * (e.g. 'left'/'top' etc) are also placed in this category. Frames with different * active geometry roots are in different PaintedLayers, so that we can animate the * geometry root by changing its transform (either on the main thread or in the * compositor). * * nsDisplayListBuilder constructs a tree of these (for fast traversals) and assigns * one for each display item. * * The animated geometry root for a display item is required to be a descendant (or * equal to) the item's ReferenceFrame(), which means that we will fall back to * returning aItem->ReferenceFrame() when we can't find another animated geometry root. * * The animated geometry root isn't strongly defined for a frame as transforms and * background-attachment:fixed can cause it to vary between display items for a given * frame. */structAnimatedGeometryRoot{AnimatedGeometryRoot(nsIFrame*aFrame,AnimatedGeometryRoot*aParent):mFrame(aFrame),mParentAGR(aParent){}operatornsIFrame*(){returnmFrame;}nsIFrame*operator->()const{returnmFrame;}void*operatornew(size_taSize,nsDisplayListBuilder*aBuilder);nsIFrame*mFrame;AnimatedGeometryRoot*mParentAGR;};namespacemozilla{/** * An active scrolled root (ASR) is similar to an animated geometry root (AGR). * The differences are: * - ASRs are only created for async-scrollable scroll frames. This is a * (hopefully) temporary restriction. In the future we will want to create * ASRs for all the things that are currently creating AGRs, and then * replace AGRs with ASRs and rename them from "active scrolled root" to * "animated geometry root". * - ASR objects are created during display list construction by the nsIFrames * that induce ASRs. This is done using AutoCurrentActiveScrolledRootSetter. * The current ASR is returned by nsDisplayListBuilder::CurrentActiveScrolledRoot(). * - There is no way to go from an nsIFrame pointer to the ASR of that frame. * If you need to look up an ASR after display list construction, you need * to store it while the AutoCurrentActiveScrolledRootSetter that creates it * is on the stack. */structActiveScrolledRoot{ActiveScrolledRoot(constActiveScrolledRoot*aParent,nsIScrollableFrame*aScrollableFrame):mParent(aParent),mScrollableFrame(aScrollableFrame),mDepth(mParent?mParent->mDepth+1:1){}staticconstActiveScrolledRoot*PickAncestor(constActiveScrolledRoot*aOne,constActiveScrolledRoot*aTwo){MOZ_ASSERT(IsAncestor(aOne,aTwo)||IsAncestor(aTwo,aOne));returnDepth(aOne)<=Depth(aTwo)?aOne:aTwo;}staticconstActiveScrolledRoot*PickDescendant(constActiveScrolledRoot*aOne,constActiveScrolledRoot*aTwo){MOZ_ASSERT(IsAncestor(aOne,aTwo)||IsAncestor(aTwo,aOne));returnDepth(aOne)>=Depth(aTwo)?aOne:aTwo;}staticboolIsAncestor(constActiveScrolledRoot*aAncestor,constActiveScrolledRoot*aDescendant);staticnsCStringToString(constmozilla::ActiveScrolledRoot*aActiveScrolledRoot);// Call this when inserting an ancestor.voidIncrementDepth(){mDepth++;}constActiveScrolledRoot*mParent;nsIScrollableFrame*mScrollableFrame;private:staticuint32_tDepth(constActiveScrolledRoot*aActiveScrolledRoot){returnaActiveScrolledRoot?aActiveScrolledRoot->mDepth:0;}uint32_tmDepth;};}enumclassnsDisplayListBuilderMode:uint8_t{PAINTING,EVENT_DELIVERY,PLUGIN_GEOMETRY,FRAME_VISIBILITY,TRANSFORM_COMPUTATION,GENERATE_GLYPH,PAINTING_SELECTION_BACKGROUND};/** * This manages a display list and is passed as a parameter to * nsIFrame::BuildDisplayList. * It contains the parameters that don't change from frame to frame and manages * the display list memory using an arena. It also establishes the reference * coordinate system for all display list items. Some of the parameters are * available from the prescontext/presshell, but we copy them into the builder * for faster/more convenient access. */classnsDisplayListBuilder{typedefmozilla::LayoutDeviceIntRectLayoutDeviceIntRect;typedefmozilla::LayoutDeviceIntRegionLayoutDeviceIntRegion;/** * This manages status of a 3d context to collect visible rects of * descendants and passing a dirty rect. * * Since some transforms maybe singular, passing visible rects or * the dirty rect level by level from parent to children may get a * wrong result, being different from the result of appling with * effective transform directly. * * nsFrame::BuildDisplayListForStackingContext() uses * AutoPreserves3DContext to install an instance on the builder. * * \see AutoAccumulateTransform, AutoAccumulateRect, * AutoPreserves3DContext, Accumulate, GetCurrentTransform, * StartRoot. */classPreserves3DContext{public:typedefmozilla::gfx::Matrix4x4Matrix4x4;Preserves3DContext():mAccumulatedRectLevels(0){}Preserves3DContext(constPreserves3DContext&aOther):mAccumulatedTransform(),mAccumulatedRect(),mAccumulatedRectLevels(0),mDirtyRect(aOther.mDirtyRect){}// Accmulate transforms of ancestors on the preserves-3d chain.Matrix4x4mAccumulatedTransform;// Accmulate visible rect of descendants in the preserves-3d context.nsRectmAccumulatedRect;// How far this frame is from the root of the current 3d context.intmAccumulatedRectLevels;nsRectmDirtyRect;};/** * A frame can be in one of three states of AGR. * AGR_NO means the frame is not an AGR for now. * AGR_YES means the frame is an AGR for now. * AGR_MAYBE means the frame is not an AGR for now, but a transition * to AGR_YES without restyling is possible. */enumAGRState{AGR_NO,AGR_YES,AGR_MAYBE};public:typedefmozilla::FrameLayerBuilderFrameLayerBuilder;typedefmozilla::DisplayItemClipDisplayItemClip;typedefmozilla::DisplayItemClipChainDisplayItemClipChain;typedefmozilla::DisplayListClipStateDisplayListClipState;typedefmozilla::ActiveScrolledRootActiveScrolledRoot;typedefnsIWidget::ThemeGeometryThemeGeometry;typedefmozilla::layers::LayerLayer;typedefmozilla::layers::FrameMetricsFrameMetrics;typedefmozilla::layers::FrameMetrics::ViewIDViewID;typedefmozilla::gfx::Matrix4x4Matrix4x4;/** * @param aReferenceFrame the frame at the root of the subtree; its origin * is the origin of the reference coordinate system for this display list * @param aMode encodes what the builder is being used for. * @param aBuildCaret whether or not we should include the caret in any * display lists that we make. */nsDisplayListBuilder(nsIFrame*aReferenceFrame,nsDisplayListBuilderModeaMode,boolaBuildCaret);~nsDisplayListBuilder();voidSetWillComputePluginGeometry(boolaWillComputePluginGeometry){mWillComputePluginGeometry=aWillComputePluginGeometry;}voidSetForPluginGeometry(){NS_ASSERTION(mMode==nsDisplayListBuilderMode::PAINTING,"Can only switch from PAINTING to PLUGIN_GEOMETRY");NS_ASSERTION(mWillComputePluginGeometry,"Should have signalled this in advance");mMode=nsDisplayListBuilderMode::PLUGIN_GEOMETRY;}mozilla::layers::LayerManager*GetWidgetLayerManager(nsView**aView=nullptr);/** * @return true if the display is being built in order to determine which * frame is under the mouse position. */boolIsForEventDelivery(){returnmMode==nsDisplayListBuilderMode::EVENT_DELIVERY;}/** * Be careful with this. The display list will be built in PAINTING mode * first and then switched to PLUGIN_GEOMETRY before a second call to * ComputeVisibility. * @return true if the display list is being built to compute geometry * for plugins. */boolIsForPluginGeometry(){returnmMode==nsDisplayListBuilderMode::PLUGIN_GEOMETRY;}/** * @return true if the display list is being built for painting. */boolIsForPainting(){returnmMode==nsDisplayListBuilderMode::PAINTING;}/** * @return true if the display list is being built for determining frame * visibility. */boolIsForFrameVisibility(){returnmMode==nsDisplayListBuilderMode::FRAME_VISIBILITY;}/** * @return true if the display list is being built for creating the glyph * mask from text items. */boolIsForGenerateGlyphMask(){returnmMode==nsDisplayListBuilderMode::GENERATE_GLYPH;}/** * @return true if the display list is being built for painting selection * background. */boolIsForPaintingSelectionBG(){returnmMode==nsDisplayListBuilderMode::PAINTING_SELECTION_BACKGROUND;}boolWillComputePluginGeometry(){returnmWillComputePluginGeometry;}/** * @return true if "painting is suppressed" during page load and we * should paint only the background of the document. */boolIsBackgroundOnly(){NS_ASSERTION(mPresShellStates.Length()>0,"don't call this if we're not in a presshell");returnCurrentPresShellState()->mIsBackgroundOnly;}/** * @return true if the currently active BuildDisplayList call is being * applied to a frame at the root of a pseudo stacking context. A pseudo * stacking context is either a real stacking context or basically what * CSS2.1 appendix E refers to with "treat the element as if it created * a new stacking context */boolIsAtRootOfPseudoStackingContext(){returnmIsAtRootOfPseudoStackingContext;}/** * @return the selection that painting should be restricted to (or nullptr * in the normal unrestricted case) */nsISelection*GetBoundingSelection(){returnmBoundingSelection;}/** * @return the root of given frame's (sub)tree, whose origin * establishes the coordinate system for the child display items. */constnsIFrame*FindReferenceFrameFor(constnsIFrame*aFrame,nsPoint*aOffset=nullptr);/** * @return the root of the display list's frame (sub)tree, whose origin * establishes the coordinate system for the display list */nsIFrame*RootReferenceFrame(){returnmReferenceFrame;}/** * @return a point pt such that adding pt to a coordinate relative to aFrame * makes it relative to ReferenceFrame(), i.e., returns * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in * the appunits of aFrame. */constnsPointToReferenceFrame(constnsIFrame*aFrame){nsPointresult;FindReferenceFrameFor(aFrame,&result);returnresult;}/** * When building the display list, the scrollframe aFrame will be "ignored" * for the purposes of clipping, and its scrollbars will be hidden. We use * this to allow RenderOffscreen to render a whole document without beign * clipped by the viewport or drawing the viewport scrollbars. */voidSetIgnoreScrollFrame(nsIFrame*aFrame){mIgnoreScrollFrame=aFrame;}/** * Get the scrollframe to ignore, if any. */nsIFrame*GetIgnoreScrollFrame(){returnmIgnoreScrollFrame;}/** * Get the ViewID of the nearest scrolling ancestor frame. */ViewIDGetCurrentScrollParentId()const{returnmCurrentScrollParentId;}/** * Get and set the flag that indicates if scroll parents should have layers * forcibly created. This flag is set when a deeply nested scrollframe has * a displayport, and for scroll handoff to work properly the ancestor * scrollframes should also get their own scrollable layers. */voidForceLayerForScrollParent(){mForceLayerForScrollParent=true;}/** * Get the ViewID and the scrollbar flags corresponding to the scrollbar for * which we are building display items at the moment. */ViewIDGetCurrentScrollbarTarget()const{returnmCurrentScrollbarTarget;}uint32_tGetCurrentScrollbarFlags()const{returnmCurrentScrollbarFlags;}/** * Returns true if building a scrollbar, and the scrollbar will not be * layerized. */boolIsBuildingNonLayerizedScrollbar()const{returnmIsBuildingScrollbar&&!mCurrentScrollbarWillHaveLayer;}/** * Calling this setter makes us include all out-of-flow descendant * frames in the display list, wherever they may be positioned (even * outside the dirty rects). */voidSetIncludeAllOutOfFlows(){mIncludeAllOutOfFlows=true;}boolGetIncludeAllOutOfFlows()const{returnmIncludeAllOutOfFlows;}/** * Calling this setter makes us exclude all leaf frames that aren't * selected. */voidSetSelectedFramesOnly(){mSelectedFramesOnly=true;}boolGetSelectedFramesOnly(){returnmSelectedFramesOnly;}/** * Calling this setter makes us compute accurate visible regions at the cost * of performance if regions get very complex. */voidSetAccurateVisibleRegions(){mAccurateVisibleRegions=true;}boolGetAccurateVisibleRegions(){returnmAccurateVisibleRegions;}/** * @return Returns true if we should include the caret in any display lists * that we make. */boolIsBuildingCaret(){returnmBuildCaret;}/** * Allows callers to selectively override the regular paint suppression checks, * so that methods like GetFrameForPoint work when painting is suppressed. */voidIgnorePaintSuppression(){mIgnoreSuppression=true;}/** * @return Returns if this builder will ignore paint suppression. */boolIsIgnoringPaintSuppression(){returnmIgnoreSuppression;}/** * Call this if we're doing normal painting to the window. */voidSetPaintingToWindow(boolaToWindow){mIsPaintingToWindow=aToWindow;}boolIsPaintingToWindow()const{returnmIsPaintingToWindow;}/** * Call this to prevent descending into subdocuments. */voidSetDescendIntoSubdocuments(boolaDescend){mDescendIntoSubdocuments=aDescend;}boolGetDescendIntoSubdocuments(){returnmDescendIntoSubdocuments;}/** * Get dirty rect relative to current frame (the frame that we're calling * BuildDisplayList on right now). */constnsRect&GetDirtyRect(){returnmDirtyRect;}constnsIFrame*GetCurrentFrame(){returnmCurrentFrame;}constnsIFrame*GetCurrentReferenceFrame(){returnmCurrentReferenceFrame;}constnsPoint&GetCurrentFrameOffsetToReferenceFrame(){returnmCurrentOffsetToReferenceFrame;}AnimatedGeometryRoot*GetCurrentAnimatedGeometryRoot(){returnmCurrentAGR;}AnimatedGeometryRoot*GetRootAnimatedGeometryRoot(){return&mRootAGR;}voidRecomputeCurrentAnimatedGeometryRoot();/** * Returns true if merging and flattening of display lists should be * performed while computing visibility. */boolAllowMergingAndFlattening(){returnmAllowMergingAndFlattening;}voidSetAllowMergingAndFlattening(boolaAllow){mAllowMergingAndFlattening=aAllow;}nsDisplayLayerEventRegions*GetLayerEventRegions(){returnmLayerEventRegions;}voidSetLayerEventRegions(nsDisplayLayerEventRegions*aItem){mLayerEventRegions=aItem;}boolIsBuildingLayerEventRegions();staticboolLayerEventRegionsEnabled();boolIsInsidePointerEventsNoneDoc(){returnCurrentPresShellState()->mInsidePointerEventsNoneDoc;}boolGetAncestorHasApzAwareEventHandler(){returnmAncestorHasApzAwareEventHandler;}voidSetAncestorHasApzAwareEventHandler(boolaValue){mAncestorHasApzAwareEventHandler=aValue;}boolHaveScrollableDisplayPort()const{returnmHaveScrollableDisplayPort;}voidSetHaveScrollableDisplayPort(){mHaveScrollableDisplayPort=true;}boolSetIsCompositingCheap(boolaCompositingCheap){booltemp=mIsCompositingCheap;mIsCompositingCheap=aCompositingCheap;returntemp;}boolIsCompositingCheap()const{returnmIsCompositingCheap;}/** * Display the caret if needed. */voidDisplayCaret(nsIFrame*aFrame,constnsRect&aDirtyRect,nsDisplayList*aList){nsIFrame*frame=GetCaretFrame();if(aFrame==frame){frame->DisplayCaret(this,aDirtyRect,aList);}}/** * Get the frame that the caret is supposed to draw in. * If the caret is currently invisible, this will be null. */nsIFrame*GetCaretFrame(){returnCurrentPresShellState()->mCaretFrame;}/** * Get the rectangle we're supposed to draw the caret into. */constnsRect&GetCaretRect(){returnCurrentPresShellState()->mCaretRect;}/** * Get the caret associated with the current presshell. */nsCaret*GetCaret();/** * Notify the display list builder that we're entering a presshell. * aReferenceFrame should be a frame in the new presshell. * aPointerEventsNoneDoc should be set to true if the frame generating this * document is pointer-events:none. */voidEnterPresShell(nsIFrame*aReferenceFrame,boolaPointerEventsNoneDoc=false);/** * For print-preview documents, we sometimes need to build display items for * the same frames multiple times in the same presentation, with different * clipping. Between each such batch of items, call * ResetMarkedFramesForDisplayList to make sure that the results of * MarkFramesForDisplayList do not carry over between batches. */voidResetMarkedFramesForDisplayList();/** * Notify the display list builder that we're leaving a presshell. */voidLeavePresShell(nsIFrame*aReferenceFrame,nsDisplayList*aPaintedContents);/** * Returns true if we're currently building a display list that's * directly or indirectly under an nsDisplayTransform. */boolIsInTransform()const{returnmInTransform;}/** * Indicate whether or not we're directly or indirectly under and * nsDisplayTransform or SVG foreignObject. */voidSetInTransform(boolaInTransform){mInTransform=aInTransform;}/** * Return true if we're currently building a display list for a * nested presshell. */boolIsInSubdocument(){returnmPresShellStates.Length()>1;}/** * Return true if we're currently building a display list for the presshell * of a chrome document, or if we're building the display list for a popup. */boolIsInChromeDocumentOrPopup(){returnmIsInChromePresContext||mIsBuildingForPopup;}/** * @return true if images have been set to decode synchronously. */boolShouldSyncDecodeImages(){returnmSyncDecodeImages;}/** * Indicates whether we should synchronously decode images. If true, we decode * and draw whatever image data has been loaded. If false, we just draw * whatever has already been decoded. */voidSetSyncDecodeImages(boolaSyncDecodeImages){mSyncDecodeImages=aSyncDecodeImages;}/** * Helper method to generate background painting flags based on the * information available in the display list builder. Currently only * accounts for mSyncDecodeImages. */uint32_tGetBackgroundPaintFlags();/** * Subtracts aRegion from *aVisibleRegion. We avoid letting * aVisibleRegion become overcomplex by simplifying it if necessary --- * unless mAccurateVisibleRegions is set, in which case we let it * get arbitrarily complex. */voidSubtractFromVisibleRegion(nsRegion*aVisibleRegion,constnsRegion&aRegion);/** * Mark the frames in aFrames to be displayed if they intersect aDirtyRect * (which is relative to aDirtyFrame). If the frames have placeholders * that might not be displayed, we mark the placeholders and their ancestors * to ensure that display list construction descends into them * anyway. nsDisplayListBuilder will take care of unmarking them when it is * destroyed. */voidMarkFramesForDisplayList(nsIFrame*aDirtyFrame,constnsFrameList&aFrames,constnsRect&aDirtyRect);/** * Mark all child frames that Preserve3D() as needing display. * Because these frames include transforms set on their parent, dirty rects * for intermediate frames may be empty, yet child frames could still be visible. */voidMarkPreserve3DFramesForDisplayList(nsIFrame*aDirtyFrame);constnsTArray<ThemeGeometry>&GetThemeGeometries(){returnmThemeGeometries;}/** * Returns true if we need to descend into this frame when building * the display list, even though it doesn't intersect the dirty * rect, because it may have out-of-flows that do so. */boolShouldDescendIntoFrame(nsIFrame*aFrame)const{return(aFrame->GetStateBits()&NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)||GetIncludeAllOutOfFlows();}/** * Notifies the builder that a particular themed widget exists * at the given rectangle within the currently built display list. * For certain appearance values (currently only NS_THEME_TOOLBAR and * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list * construction, for every themed widget of the right type within the * display list, except for themed widgets which are transformed or have * effects applied to them (e.g. CSS opacity or filters). * * @param aWidgetType the -moz-appearance value for the themed widget * @param aRect the device-pixel rect relative to the widget's displayRoot * for the themed widget */voidRegisterThemeGeometry(uint8_taWidgetType,constmozilla::LayoutDeviceIntRect&aRect){if(mIsPaintingToWindow){mThemeGeometries.AppendElement(ThemeGeometry(aWidgetType,aRect));}}/** * Adjusts mWindowDraggingRegion to take into account aFrame. If aFrame's * -moz-window-dragging value is |drag|, its border box is added to the * collected dragging region; if the value is |no-drag|, the border box is * subtracted from the region; if the value is |default|, that frame does * not influence the window dragging region. */voidAdjustWindowDraggingRegion(nsIFrame*aFrame);LayoutDeviceIntRegionGetWindowDraggingRegion()const;/** * Allocate memory in our arena. It will only be freed when this display list * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem * destructors are called as soon as the item is no longer used. */void*Allocate(size_taSize);/** * Allocate a new ActiveScrolledRoot in the arena. Will be cleaned up * automatically when the arena goes away. */ActiveScrolledRoot*AllocateActiveScrolledRoot(constActiveScrolledRoot*aParent,nsIScrollableFrame*aScrollableFrame);/** * Allocate a new DisplayItemClipChain object in the arena. Will be cleaned * up automatically when the arena goes away. */constDisplayItemClipChain*AllocateDisplayItemClipChain(constDisplayItemClip&aClip,constActiveScrolledRoot*aASR,constDisplayItemClipChain*aParent);/** * Intersect two clip chains, allocating the new clip chain items in this * builder's arena. The result is parented to aAncestor, and no intersections * happen past aAncestor's ASR. * That means aAncestor has to be living in this builder's arena already. * aLeafClip1 and aLeafClip2 only need to outlive the call to this function, * their values are copied into the newly-allocated intersected clip chain * and this function does not hold on to any pointers to them. */constDisplayItemClipChain*CreateClipChainIntersection(constDisplayItemClipChain*aAncestor,constDisplayItemClipChain*aLeafClip1,constDisplayItemClipChain*aLeafClip2);/** * Clone the supplied clip chain's chain items into this builder's arena. */constDisplayItemClipChain*CopyWholeChain(constDisplayItemClipChain*aClipChain);/** * Only used for containerful root scrolling. This is a workaround. */voidSetActiveScrolledRootForRootScrollframe(constActiveScrolledRoot*aASR){mActiveScrolledRootForRootScrollframe=aASR;}constActiveScrolledRoot*ActiveScrolledRootForRootScrollframe()const{returnmActiveScrolledRootForRootScrollframe;}/** * Transfer off main thread animations to the layer. May be called * with aBuilder and aItem both null, but only if the caller has * already checked that off main thread animations should be sent to * the layer. When they are both null, the animations are added to * the layer as pending animations. */staticvoidAddAnimationsAndTransitionsToLayer(Layer*aLayer,nsDisplayListBuilder*aBuilder,nsDisplayItem*aItem,nsIFrame*aFrame,nsCSSPropertyIDaProperty);/** * A helper class to temporarily set the value of * mIsAtRootOfPseudoStackingContext, and temporarily * set mCurrentFrame and related state. Also temporarily sets mDirtyRect. * aDirtyRect is relative to aForChild. */classAutoBuildingDisplayList;friendclassAutoBuildingDisplayList;classAutoBuildingDisplayList{public:AutoBuildingDisplayList(nsDisplayListBuilder*aBuilder,nsIFrame*aForChild,constnsRect&aDirtyRect,boolaIsRoot):mBuilder(aBuilder),mPrevFrame(aBuilder->mCurrentFrame),mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),mPrevLayerEventRegions(aBuilder->mLayerEventRegions),mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),mPrevDirtyRect(aBuilder->mDirtyRect),mPrevAGR(aBuilder->mCurrentAGR),mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler),mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems){if(aForChild->IsTransformed()){aBuilder->mCurrentOffsetToReferenceFrame=nsPoint();aBuilder->mCurrentReferenceFrame=aForChild;}elseif(aBuilder->mCurrentFrame==aForChild->GetParent()){aBuilder->mCurrentOffsetToReferenceFrame+=aForChild->GetPosition();}else{aBuilder->mCurrentReferenceFrame=aBuilder->FindReferenceFrameFor(aForChild,&aBuilder->mCurrentOffsetToReferenceFrame);}mCurrentAGRState=aBuilder->IsAnimatedGeometryRoot(aForChild);if(aBuilder->mCurrentFrame==aForChild->GetParent()){if(mCurrentAGRState==AGR_YES){aBuilder->mCurrentAGR=aBuilder->WrapAGRForFrame(aForChild,aBuilder->mCurrentAGR);}}elseif(aForChild!=aBuilder->mCurrentFrame){aBuilder->mCurrentAGR=aBuilder->FindAnimatedGeometryRootFor(aForChild);}MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),*aBuilder->mCurrentAGR));aBuilder->mCurrentFrame=aForChild;aBuilder->mDirtyRect=aDirtyRect;aBuilder->mIsAtRootOfPseudoStackingContext=aIsRoot;}voidSetDirtyRect(constnsRect&aRect){mBuilder->mDirtyRect=aRect;}voidSetReferenceFrameAndCurrentOffset(constnsIFrame*aFrame,constnsPoint&aOffset){mBuilder->mCurrentReferenceFrame=aFrame;mBuilder->mCurrentOffsetToReferenceFrame=aOffset;}// Return the previous frame's animated geometry root, whether or not the// current frame is an immediate descendant.constnsIFrame*GetPrevAnimatedGeometryRoot()const{returnmPrevAnimatedGeometryRoot;}boolIsAnimatedGeometryRoot()const{returnmCurrentAGRState==AGR_YES;}boolMaybeAnimatedGeometryRoot()const{returnmCurrentAGRState==AGR_MAYBE;}voidRestoreBuildingInvisibleItemsValue(){mBuilder->mBuildingInvisibleItems=mPrevBuildingInvisibleItems;}~AutoBuildingDisplayList(){mBuilder->mCurrentFrame=mPrevFrame;mBuilder->mCurrentReferenceFrame=mPrevReferenceFrame;mBuilder->mLayerEventRegions=mPrevLayerEventRegions;mBuilder->mCurrentOffsetToReferenceFrame=mPrevOffset;mBuilder->mDirtyRect=mPrevDirtyRect;mBuilder->mCurrentAGR=mPrevAGR;mBuilder->mIsAtRootOfPseudoStackingContext=mPrevIsAtRootOfPseudoStackingContext;mBuilder->mAncestorHasApzAwareEventHandler=mPrevAncestorHasApzAwareEventHandler;mBuilder->mBuildingInvisibleItems=mPrevBuildingInvisibleItems;}private:nsDisplayListBuilder*mBuilder;AGRStatemCurrentAGRState;constnsIFrame*mPrevFrame;constnsIFrame*mPrevReferenceFrame;nsIFrame*mPrevAnimatedGeometryRoot;nsDisplayLayerEventRegions*mPrevLayerEventRegions;nsPointmPrevOffset;nsRectmPrevDirtyRect;AnimatedGeometryRoot*mPrevAGR;boolmPrevIsAtRootOfPseudoStackingContext;boolmPrevAncestorHasApzAwareEventHandler;boolmPrevBuildingInvisibleItems;};/** * A helper class to temporarily set the value of mInTransform. */classAutoInTransformSetter;friendclassAutoInTransformSetter;classAutoInTransformSetter{public:AutoInTransformSetter(nsDisplayListBuilder*aBuilder,boolaInTransform):mBuilder(aBuilder),mOldValue(aBuilder->mInTransform){aBuilder->mInTransform=aInTransform;}~AutoInTransformSetter(){mBuilder->mInTransform=mOldValue;}private:nsDisplayListBuilder*mBuilder;boolmOldValue;};classAutoSaveRestorePerspectiveIndex;friendclassAutoSaveRestorePerspectiveIndex;classAutoSaveRestorePerspectiveIndex{public:AutoSaveRestorePerspectiveIndex(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):mBuilder(nullptr){if(aFrame->ChildrenHavePerspective()){mBuilder=aBuilder;mCachedItemIndex=aBuilder->mPerspectiveItemIndex;aBuilder->mPerspectiveItemIndex=0;}}~AutoSaveRestorePerspectiveIndex(){if(mBuilder){mBuilder->mPerspectiveItemIndex=mCachedItemIndex;}}private:nsDisplayListBuilder*mBuilder;uint32_tmCachedItemIndex;};/** * A helper class to temporarily set the value of mCurrentScrollParentId. */classAutoCurrentScrollParentIdSetter;friendclassAutoCurrentScrollParentIdSetter;classAutoCurrentScrollParentIdSetter{public:AutoCurrentScrollParentIdSetter(nsDisplayListBuilder*aBuilder,ViewIDaScrollId):mBuilder(aBuilder),mOldValue(aBuilder->mCurrentScrollParentId),mOldForceLayer(aBuilder->mForceLayerForScrollParent){// If this AutoCurrentScrollParentIdSetter has the same scrollId as the// previous one on the stack, then that means the scrollframe that// created this isn't actually scrollable and cannot participate in// scroll handoff. We set mCanBeScrollParent to false to indicate this.mCanBeScrollParent=(mOldValue!=aScrollId);aBuilder->mCurrentScrollParentId=aScrollId;aBuilder->mForceLayerForScrollParent=false;}boolShouldForceLayerForScrollParent()const{// Only scrollframes participating in scroll handoff can be forced to// layerizereturnmCanBeScrollParent&&mBuilder->mForceLayerForScrollParent;};~AutoCurrentScrollParentIdSetter(){mBuilder->mCurrentScrollParentId=mOldValue;if(mCanBeScrollParent){// If this flag is set, caller code is responsible for having dealt// with the current value of mBuilder->mForceLayerForScrollParent, so// we can just restore the old value.mBuilder->mForceLayerForScrollParent=mOldForceLayer;}else{// Otherwise we need to keep propagating the force-layerization flag// upwards to the next ancestor scrollframe that does participate in// scroll handoff.mBuilder->mForceLayerForScrollParent|=mOldForceLayer;}}private:nsDisplayListBuilder*mBuilder;ViewIDmOldValue;boolmOldForceLayer;boolmCanBeScrollParent;};/** * Used to update the current active scrolled root on the display list * builder, and to create new active scrolled roots. */classAutoCurrentActiveScrolledRootSetter;friendclassAutoCurrentActiveScrolledRootSetter;classAutoCurrentActiveScrolledRootSetter{public:explicitAutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder*aBuilder):mBuilder(aBuilder),mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot),mContentClipASR(aBuilder->ClipState().GetContentClipASR()),mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length()),mUsed(false){}~AutoCurrentActiveScrolledRootSetter(){mBuilder->mCurrentActiveScrolledRoot=mSavedActiveScrolledRoot;}voidSetCurrentActiveScrolledRoot(constActiveScrolledRoot*aActiveScrolledRoot){MOZ_ASSERT(!mUsed);// Set the builder's mCurrentActiveScrolledRoot.mBuilder->mCurrentActiveScrolledRoot=aActiveScrolledRoot;// We also need to adjust the builder's mCurrentContainerASR.// mCurrentContainerASR needs to be an ASR that all the container's// contents have finite bounds with respect to. If aActiveScrolledRoot// is an ancestor ASR of mCurrentContainerASR, that means we need to// set mCurrentContainerASR to aActiveScrolledRoot, because otherwise// the items that will be created with aActiveScrolledRoot wouldn't// have finite bounds with respect to mCurrentContainerASR. There's one// exception, in the case where there's a content clip on the builder// that is scrolled by a descendant ASR of aActiveScrolledRoot. This// content clip will clip all items that are created while this// AutoCurrentActiveScrolledRootSetter exists. This means that the items// created during our lifetime will have finite bounds with respect to// the content clip's ASR, even if the items' actual ASR is an ancestor// of that. And it also means that mCurrentContainerASR only needs to be// set to the content clip's ASR and not all the way to aActiveScrolledRoot.// This case is tested by fixed-pos-scrolled-clip-opacity-layerize.html// and fixed-pos-scrolled-clip-opacity-inside-layerize.html.// finiteBoundsASR is the leafmost ASR that all items created during// object's lifetime have finite bounds with respect to.constActiveScrolledRoot*finiteBoundsASR=ActiveScrolledRoot::PickDescendant(mContentClipASR,aActiveScrolledRoot);// mCurrentContainerASR is adjusted so that it's still an ancestor of// finiteBoundsASR.mBuilder->mCurrentContainerASR=ActiveScrolledRoot::PickAncestor(mBuilder->mCurrentContainerASR,finiteBoundsASR);mUsed=true;}voidEnterScrollFrame(nsIScrollableFrame*aScrollableFrame){MOZ_ASSERT(!mUsed);ActiveScrolledRoot*asr=mBuilder->AllocateActiveScrolledRoot(mBuilder->mCurrentActiveScrolledRoot,aScrollableFrame);mBuilder->mCurrentActiveScrolledRoot=asr;mUsed=true;}voidInsertScrollFrame(nsIScrollableFrame*aScrollableFrame);private:nsDisplayListBuilder*mBuilder;/** * The builder's mCurrentActiveScrolledRoot at construction time which * needs to be restored at destruction time. */constActiveScrolledRoot*mSavedActiveScrolledRoot;/** * If there's a content clip on the builder at construction time, then * mContentClipASR is that content clip's ASR, otherwise null. The * assumption is that the content clip doesn't get relaxed while this * object is on the stack. */constActiveScrolledRoot*mContentClipASR;/** * InsertScrollFrame needs to mutate existing ASRs (those that were * created while this object was on the stack), and mDescendantsStartIndex * makes it easier to skip ASRs that were created in the past. */size_tmDescendantsStartIndex;/** * Flag to make sure that only one of SetCurrentActiveScrolledRoot / * EnterScrollFrame / InsertScrollFrame is called per instance of this * class. */boolmUsed;};/** * Keeps track of the innermost ASR that can be used as the ASR for a * container item that wraps all items that were created while this * object was on the stack. * The rule is: all child items of the container item need to have * clipped bounds with respect to the container ASR. */classAutoContainerASRTracker;friendclassAutoContainerASRTracker;classAutoContainerASRTracker{public:explicitAutoContainerASRTracker(nsDisplayListBuilder*aBuilder):mBuilder(aBuilder),mSavedContainerASR(aBuilder->mCurrentContainerASR){mBuilder->mCurrentContainerASR=ActiveScrolledRoot::PickDescendant(mBuilder->ClipState().GetContentClipASR(),mBuilder->mCurrentActiveScrolledRoot);}constActiveScrolledRoot*GetContainerASR(){returnmBuilder->mCurrentContainerASR;}~AutoContainerASRTracker(){mBuilder->mCurrentContainerASR=ActiveScrolledRoot::PickAncestor(mBuilder->mCurrentContainerASR,mSavedContainerASR);}private:nsDisplayListBuilder*mBuilder;constActiveScrolledRoot*mSavedContainerASR;};/** * A helper class to temporarily set the value of mCurrentScrollbarTarget * and mCurrentScrollbarFlags. */classAutoCurrentScrollbarInfoSetter;friendclassAutoCurrentScrollbarInfoSetter;classAutoCurrentScrollbarInfoSetter{public:AutoCurrentScrollbarInfoSetter(nsDisplayListBuilder*aBuilder,ViewIDaScrollTargetID,uint32_taScrollbarFlags,boolaWillHaveLayer):mBuilder(aBuilder){aBuilder->mIsBuildingScrollbar=true;aBuilder->mCurrentScrollbarTarget=aScrollTargetID;aBuilder->mCurrentScrollbarFlags=aScrollbarFlags;aBuilder->mCurrentScrollbarWillHaveLayer=aWillHaveLayer;}~AutoCurrentScrollbarInfoSetter(){// No need to restore old values because scrollbars cannot be nested.mBuilder->mIsBuildingScrollbar=false;mBuilder->mCurrentScrollbarTarget=FrameMetrics::NULL_SCROLL_ID;mBuilder->mCurrentScrollbarFlags=0;mBuilder->mCurrentScrollbarWillHaveLayer=false;}private:nsDisplayListBuilder*mBuilder;};/** * A helper class to track current effective transform for items. * * For frames that is Combines3DTransformWithAncestors(), we need to * apply all transforms of ancestors on the same preserves3D chain * on the bounds of current frame to the coordination of the 3D * context root. The 3D context root computes it's bounds from * these transformed bounds. */classAutoAccumulateTransform;friendclassAutoAccumulateTransform;classAutoAccumulateTransform{public:typedefmozilla::gfx::Matrix4x4Matrix4x4;explicitAutoAccumulateTransform(nsDisplayListBuilder*aBuilder):mBuilder(aBuilder),mSavedTransform(aBuilder->mPreserves3DCtx.mAccumulatedTransform){}~AutoAccumulateTransform(){mBuilder->mPreserves3DCtx.mAccumulatedTransform=mSavedTransform;}voidAccumulate(constMatrix4x4&aTransform){mBuilder->mPreserves3DCtx.mAccumulatedTransform=aTransform*mBuilder->mPreserves3DCtx.mAccumulatedTransform;}constMatrix4x4&GetCurrentTransform(){returnmBuilder->mPreserves3DCtx.mAccumulatedTransform;}voidStartRoot(){mBuilder->mPreserves3DCtx.mAccumulatedTransform=Matrix4x4();}private:nsDisplayListBuilder*mBuilder;Matrix4x4mSavedTransform;};/** * A helper class to collect bounds rects of descendants. * * For a 3D context root, it's bounds is computed from the bounds of * descendants. If we transform bounds frame by frame applying * transforms, the bounds may turn to empty for any singular * transform on the path, but it is not empty for the accumulated * transform. */classAutoAccumulateRect;friendclassAutoAccumulateRect;classAutoAccumulateRect{public:explicitAutoAccumulateRect(nsDisplayListBuilder*aBuilder):mBuilder(aBuilder),mSavedRect(aBuilder->mPreserves3DCtx.mAccumulatedRect){aBuilder->mPreserves3DCtx.mAccumulatedRect=nsRect();aBuilder->mPreserves3DCtx.mAccumulatedRectLevels++;}~AutoAccumulateRect(){mBuilder->mPreserves3DCtx.mAccumulatedRect=mSavedRect;mBuilder->mPreserves3DCtx.mAccumulatedRectLevels--;}private:nsDisplayListBuilder*mBuilder;nsRectmSavedRect;};voidAccumulateRect(constnsRect&aRect){mPreserves3DCtx.mAccumulatedRect.UnionRect(mPreserves3DCtx.mAccumulatedRect,aRect);}constnsRect&GetAccumulatedRect(){returnmPreserves3DCtx.mAccumulatedRect;}/** * The level is increased by one for items establishing 3D rendering * context and starting a new accumulation. */intGetAccumulatedRectLevels(){returnmPreserves3DCtx.mAccumulatedRectLevels;}// Helpers for tablesnsDisplayTableItem*GetCurrentTableItem(){returnmCurrentTableItem;}voidSetCurrentTableItem(nsDisplayTableItem*aTableItem){mCurrentTableItem=aTableItem;}structOutOfFlowDisplayData{OutOfFlowDisplayData(constDisplayItemClipChain*aContainingBlockClipChain,constDisplayItemClipChain*aCombinedClipChain,constActiveScrolledRoot*aContainingBlockActiveScrolledRoot,constnsRect&aDirtyRect):mContainingBlockClipChain(aContainingBlockClipChain),mCombinedClipChain(aCombinedClipChain),mContainingBlockActiveScrolledRoot(aContainingBlockActiveScrolledRoot),mDirtyRect(aDirtyRect){}constDisplayItemClipChain*mContainingBlockClipChain;constDisplayItemClipChain*mCombinedClipChain;// only necessary for the special case of top layerconstActiveScrolledRoot*mContainingBlockActiveScrolledRoot;nsRectmDirtyRect;};NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutOfFlowDisplayDataProperty,OutOfFlowDisplayData)staticOutOfFlowDisplayData*GetOutOfFlowData(nsIFrame*aFrame){returnaFrame->GetProperty(OutOfFlowDisplayDataProperty());}nsPresContext*CurrentPresContext(){returnCurrentPresShellState()->mPresShell->GetPresContext();}OutOfFlowDisplayData*GetCurrentFixedBackgroundDisplayData(){auto&displayData=CurrentPresShellState()->mFixedBackgroundDisplayData;returndisplayData?displayData.ptr():nullptr;}/** * Accumulates the bounds of box frames that have moz-appearance * -moz-win-exclude-glass style. Used in setting glass margins on * Windows. * * We set the window opaque region (from which glass margins are computed) * to the intersection of the glass region specified here and the opaque * region computed during painting. So the excluded glass region actually * *limits* the extent of the opaque area reported to Windows. We limit it * so that changes to the computed opaque region (which can vary based on * region optimizations and the placement of UI elements) outside the * -moz-win-exclude-glass area don't affect the glass margins reported to * Windows; changing those margins willy-nilly can cause the Windows 7 glass * haze effect to jump around disconcertingly. */voidAddWindowExcludeGlassRegion(constnsRegion&bounds){mWindowExcludeGlassRegion.Or(mWindowExcludeGlassRegion,bounds);}constnsRegion&GetWindowExcludeGlassRegion(){returnmWindowExcludeGlassRegion;}/** * Accumulates opaque stuff into the window opaque region. */voidAddWindowOpaqueRegion(constnsRegion&bounds){mWindowOpaqueRegion.Or(mWindowOpaqueRegion,bounds);}/** * Returns the window opaque region built so far. This may be incomplete * since the opaque region is built during layer construction. */constnsRegion&GetWindowOpaqueRegion(){returnmWindowOpaqueRegion;}voidSetGlassDisplayItem(nsDisplayItem*aItem){if(mGlassDisplayItem){// Web pages or extensions could trigger this by using// -moz-appearance:win-borderless-glass etc on their own elements.// Keep the first one, since that will be the background of the root// windowNS_WARNING("Multiple glass backgrounds found?");}else{mGlassDisplayItem=aItem;}}boolNeedToForceTransparentSurfaceForItem(nsDisplayItem*aItem);voidSetContainsPluginItem(){mContainsPluginItem=true;}boolContainsPluginItem(){returnmContainsPluginItem;}/** * mContainsBlendMode is true if we processed a display item that * has a blend mode attached. We do this so we can insert a * nsDisplayBlendContainer in the parent stacking context. */voidSetContainsBlendMode(boolaContainsBlendMode){mContainsBlendMode=aContainsBlendMode;}boolContainsBlendMode()const{returnmContainsBlendMode;}uint32_tAllocatePerspectiveItemIndex(){returnmPerspectiveItemIndex++;}DisplayListClipState&ClipState(){returnmClipState;}constActiveScrolledRoot*CurrentActiveScrolledRoot(){returnmCurrentActiveScrolledRoot;}constActiveScrolledRoot*CurrentAncestorASRStackingContextContents(){returnmCurrentContainerASR;}/** * Add the current frame to the will-change budget if possible and * remeber the outcome. Subsequent calls to IsInWillChangeBudget * will return the same value as return here. */boolAddToWillChangeBudget(nsIFrame*aFrame,constnsSize&aSize);/** * This will add the current frame to the will-change budget the first * time it is seen. On subsequent calls this will return the same * answer. This effectively implements a first-come, first-served * allocation of the will-change budget. */boolIsInWillChangeBudget(nsIFrame*aFrame,constnsSize&aSize);voidEnterSVGEffectsContents(nsDisplayList*aHoistedItemsStorage);voidExitSVGEffectsContents();/** * Note: if changing the conditions under which scroll info layers * are created, make a corresponding change to * ScrollFrameWillBuildScrollInfoLayer() in nsSliderFrame.cpp. */boolShouldBuildScrollInfoItemsForHoisting()const{returnmSVGEffectsBuildingDepth>0;}voidAppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer*aScrollInfoItem);/** * A helper class to install/restore nsDisplayListBuilder::mPreserves3DCtx. * * mPreserves3DCtx is used by class AutoAccumulateTransform & * AutoAccumulateRect to passing data between frames in the 3D * context. If a frame create a new 3D context, it should restore * the value of mPreserves3DCtx before returning back to the parent. * This class do it for the users. */classAutoPreserves3DContext;friendclassAutoPreserves3DContext;classAutoPreserves3DContext{public:explicitAutoPreserves3DContext(nsDisplayListBuilder*aBuilder):mBuilder(aBuilder),mSavedCtx(aBuilder->mPreserves3DCtx){}~AutoPreserves3DContext(){mBuilder->mPreserves3DCtx=mSavedCtx;}private:nsDisplayListBuilder*mBuilder;Preserves3DContextmSavedCtx;};constnsRectGetPreserves3DDirtyRect(constnsIFrame*aFrame)const{returnmPreserves3DCtx.mDirtyRect;}voidSetPreserves3DDirtyRect(constnsRect&aDirtyRect){mPreserves3DCtx.mDirtyRect=aDirtyRect;}boolIsBuildingInvisibleItems()const{returnmBuildingInvisibleItems;}voidSetBuildingInvisibleItems(boolaBuildingInvisibleItems){mBuildingInvisibleItems=aBuildingInvisibleItems;}/** * This is a convenience function to ease the transition until AGRs and ASRs * are unified. */AnimatedGeometryRoot*AnimatedGeometryRootForASR(constActiveScrolledRoot*aASR);boolHitTestShouldStopAtFirstOpaque()const{returnmHitTestShouldStopAtFirstOpaque;}voidSetHitTestShouldStopAtFirstOpaque(boolaHitTestShouldStopAtFirstOpaque){mHitTestShouldStopAtFirstOpaque=aHitTestShouldStopAtFirstOpaque;}private:voidMarkOutOfFlowFrameForDisplay(nsIFrame*aDirtyFrame,nsIFrame*aFrame,constnsRect&aDirtyRect);/** * Returns whether a frame acts as an animated geometry root, optionally * returning the next ancestor to check. */AGRStateIsAnimatedGeometryRoot(nsIFrame*aFrame,nsIFrame**aParent=nullptr);/** * Returns the nearest ancestor frame to aFrame that is considered to have * (or will have) animated geometry. This can return aFrame. */nsIFrame*FindAnimatedGeometryRootFrameFor(nsIFrame*aFrame);friendclassnsDisplayCanvasBackgroundImage;friendclassnsDisplayBackgroundImage;friendclassnsDisplayFixedPosition;AnimatedGeometryRoot*FindAnimatedGeometryRootFor(nsDisplayItem*aItem);friendclassnsDisplayItem;friendclassnsDisplayOwnLayer;AnimatedGeometryRoot*FindAnimatedGeometryRootFor(nsIFrame*aFrame);AnimatedGeometryRoot*WrapAGRForFrame(nsIFrame*aAnimatedGeometryRoot,AnimatedGeometryRoot*aParent=nullptr);nsDataHashtable<nsPtrHashKey<nsIFrame>,AnimatedGeometryRoot*>mFrameToAnimatedGeometryRootMap;/** * Add the current frame to the AGR budget if possible and remember * the outcome. Subsequent calls will return the same value as * returned here. */boolAddToAGRBudget(nsIFrame*aFrame);structPresShellState{nsIPresShell*mPresShell;nsIFrame*mCaretFrame;nsRectmCaretRect;mozilla::Maybe<OutOfFlowDisplayData>mFixedBackgroundDisplayData;uint32_tmFirstFrameMarkedForDisplay;boolmIsBackgroundOnly;// This is a per-document flag turning off event handling for all content// in the document, and is set when we enter a subdocument for a pointer-// events:none frame.boolmInsidePointerEventsNoneDoc;};PresShellState*CurrentPresShellState(){NS_ASSERTION(mPresShellStates.Length()>0,"Someone forgot to enter a presshell");return&mPresShellStates[mPresShellStates.Length()-1];}structDocumentWillChangeBudget{DocumentWillChangeBudget():mBudget(0){}uint32_tmBudget;};nsIFrame*constmReferenceFrame;nsIFrame*mIgnoreScrollFrame;nsDisplayLayerEventRegions*mLayerEventRegions;staticconstsize_tkArenaAlignment=mozilla::tl::Max<NS_ALIGNMENT_OF(void*),NS_ALIGNMENT_OF(double)>::value;mozilla::ArenaAllocator<4096,kArenaAlignment>mPool;nsCOMPtr<nsISelection>mBoundingSelection;AutoTArray<PresShellState,8>mPresShellStates;AutoTArray<nsIFrame*,100>mFramesMarkedForDisplay;AutoTArray<ThemeGeometry,2>mThemeGeometries;nsDisplayTableItem*mCurrentTableItem;DisplayListClipStatemClipState;constActiveScrolledRoot*mCurrentActiveScrolledRoot;constActiveScrolledRoot*mCurrentContainerASR;// mCurrentFrame is the frame that we're currently calling (or about to call)// BuildDisplayList on.constnsIFrame*mCurrentFrame;// The reference frame for mCurrentFrame.constnsIFrame*mCurrentReferenceFrame;// The offset from mCurrentFrame to mCurrentReferenceFrame.nsPointmCurrentOffsetToReferenceFrame;AnimatedGeometryRoot*mCurrentAGR;AnimatedGeometryRootmRootAGR;// will-change budget trackernsDataHashtable<nsPtrHashKey<nsPresContext>,DocumentWillChangeBudget>mWillChangeBudget;// Any frame listed in this set is already counted in the budget// and thus is in-budget.nsTHashtable<nsPtrHashKey<nsIFrame>>mWillChangeBudgetSet;// Area of animated geometry root budget already allocateduint32_tmUsedAGRBudget;// Set of frames already counted in budgetnsTHashtable<nsPtrHashKey<nsIFrame>>mAGRBudgetSet;// Relative to mCurrentFrame.nsRectmDirtyRect;nsRegionmWindowExcludeGlassRegion;nsRegionmWindowOpaqueRegion;LayoutDeviceIntRegionmWindowDraggingRegion;LayoutDeviceIntRegionmWindowNoDraggingRegion;// The display item for the Windows window glass background, if anynsDisplayItem*mGlassDisplayItem;// A temporary list that we append scroll info items to while building// display items for the contents of frames with SVG effects.// Only non-null when ShouldBuildScrollInfoItemsForHoisting() is true.// This is a pointer and not a real nsDisplayList value because the// nsDisplayList class is defined below this class, so we can't use it here.nsDisplayList*mScrollInfoItemsForHoisting;nsTArray<ActiveScrolledRoot*>mActiveScrolledRoots;nsTArray<DisplayItemClipChain*>mClipChainsToDestroy;constActiveScrolledRoot*mActiveScrolledRootForRootScrollframe;nsDisplayListBuilderModemMode;ViewIDmCurrentScrollParentId;ViewIDmCurrentScrollbarTarget;uint32_tmCurrentScrollbarFlags;Preserves3DContextmPreserves3DCtx;uint32_tmPerspectiveItemIndex;int32_tmSVGEffectsBuildingDepth;boolmContainsBlendMode;boolmIsBuildingScrollbar;boolmCurrentScrollbarWillHaveLayer;boolmBuildCaret;boolmIgnoreSuppression;boolmIsAtRootOfPseudoStackingContext;boolmIncludeAllOutOfFlows;boolmDescendIntoSubdocuments;boolmSelectedFramesOnly;boolmAccurateVisibleRegions;boolmAllowMergingAndFlattening;boolmWillComputePluginGeometry;// True when we're building a display list that's directly or indirectly// under an nsDisplayTransformboolmInTransform;boolmIsInChromePresContext;boolmSyncDecodeImages;boolmIsPaintingToWindow;boolmIsCompositingCheap;boolmContainsPluginItem;boolmAncestorHasApzAwareEventHandler;// True when the first async-scrollable scroll frame for which we build a// display list has a display port. An async-scrollable scroll frame is one// which WantsAsyncScroll().boolmHaveScrollableDisplayPort;boolmWindowDraggingAllowed;boolmIsBuildingForPopup;boolmForceLayerForScrollParent;boolmAsyncPanZoomEnabled;boolmBuildingInvisibleItems;boolmHitTestShouldStopAtFirstOpaque;};classnsDisplayItem;classnsDisplayList;/** * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList. * nsDisplayItemLink holds the link. The lists are linked from lowest to * highest in z-order. */classnsDisplayItemLink{// This is never instantiated directly, so no need to count constructors and// destructors.protected:nsDisplayItemLink():mAbove(nullptr){}nsDisplayItem*mAbove;friendclassnsDisplayList;};/** * This is the unit of rendering and event testing. Each instance of this * class represents an entity that can be drawn on the screen, e.g., a * frame's CSS background, or a frame's text string. * * nsDisplayItems can be containers --- i.e., they can perform hit testing * and painting by recursively traversing a list of child items. * * These are arena-allocated during display list construction. A typical * subclass would just have a frame pointer, so its object would be just three * pointers (vtable, next-item, frame). * * Display items belong to a list at all times (except temporarily as they * move from one list to another). */classnsDisplayItem:publicnsDisplayItemLink{public:typedefmozilla::ContainerLayerParametersContainerLayerParameters;typedefmozilla::DisplayItemClipDisplayItemClip;typedefmozilla::DisplayItemClipChainDisplayItemClipChain;typedefmozilla::ActiveScrolledRootActiveScrolledRoot;typedefmozilla::layers::FrameMetricsFrameMetrics;typedefmozilla::layers::ScrollMetadataScrollMetadata;typedefmozilla::layers::FrameMetrics::ViewIDViewID;typedefmozilla::layers::LayerLayer;typedefmozilla::layers::LayerManagerLayerManager;typedefmozilla::layers::StackingContextHelperStackingContextHelper;typedefmozilla::layers::WebRenderCommandWebRenderCommand;typedefmozilla::layers::WebRenderParentCommandWebRenderParentCommand;typedefmozilla::layers::WebRenderDisplayItemLayerWebRenderDisplayItemLayer;typedefmozilla::LayerStateLayerState;typedefmozilla::image::imgDrawingParamsimgDrawingParams;typedefmozilla::image::DrawResultDrawResult;typedefclassmozilla::gfx::DrawTargetDrawTarget;// This is never instantiated directly (it has pure virtual methods), so no// need to count constructors and destructors.nsDisplayItem(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame);nsDisplayItem(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constActiveScrolledRoot*aActiveScrolledRoot);/** * This constructor is only used in rare cases when we need to construct * temporary items. */explicitnsDisplayItem(nsIFrame*aFrame):mFrame(aFrame),mClipChain(nullptr),mClip(nullptr),mActiveScrolledRoot(nullptr),mReferenceFrame(nullptr),mAnimatedGeometryRoot(nullptr),mForceNotVisible(false)#ifdef MOZ_DUMP_PAINTING,mPainted(false)#endif{}virtual~nsDisplayItem(){}void*operatornew(size_taSize,nsDisplayListBuilder*aBuilder){returnaBuilder->Allocate(aSize);}// Contains all the type integers for each display list item type#include"nsDisplayItemTypes.h"structHitTestState{explicitHitTestState():mInPreserves3D(false){}~HitTestState(){NS_ASSERTION(mItemBuffer.Length()==0,"mItemBuffer should have been cleared");}// Handling transform items for preserve 3D frames.boolmInPreserves3D;AutoTArray<nsDisplayItem*,100>mItemBuffer;};/** * Some consecutive items should be rendered together as a unit, e.g., * outlines for the same element. For this, we need a way for items to * identify their type. We use the type for other purposes too. */virtualTypeGetType()=0;/** * Pairing this with the GetUnderlyingFrame() pointer gives a key that * uniquely identifies this display item in the display item tree. * XXX check nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper */virtualuint32_tGetPerFrameKey(){returnuint32_t(GetType());}/** * This is called after we've constructed a display list for event handling. * When this is called, we've already ensured that aRect intersects the * item's bounds and that clipping has been taking into account. * * @param aRect the point or rect being tested, relative to the reference * frame. If the width and height are both 1 app unit, it indicates we're * hit testing a point, not a rect. * @param aState must point to a HitTestState. If you don't have one, * just create one with the default constructor and pass it in. * @param aOutFrames each item appends the frame(s) in this display item that * the rect is considered over (if any) to aOutFrames. */virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames){}/** * @return the frame that this display item is based on. This is used to sort * items by z-index and content order and for some other uses. Never * returns null. */inlinensIFrame*Frame()const{returnmFrame;}/** * Compute the used z-index of our frame; returns zero for elements to which * z-index does not apply, and for z-index:auto. * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex. */virtualint32_tZIndex()const;/** * The default bounds is the frame border rect. * @param aSnap *aSnap is set to true if the returned rect will be * snapped to nearest device pixel edges during actual drawing. * It might be set to false and snap anyway, so code computing the set of * pixels affected by this display item needs to round outwards to pixel * boundaries when *aSnap is set to false. * This does not take the item's clipping into account. * @return a rectangle relative to aBuilder->ReferenceFrame() that * contains the area drawn by this display item */virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap){*aSnap=false;returnnsRect(ToReferenceFrame(),Frame()->GetSize());}virtualnsRegionGetTightBounds(nsDisplayListBuilder*aBuilder,bool*aSnap){*aSnap=false;returnnsRegion();}/** * Returns true if nothing will be rendered inside aRect, false if uncertain. * aRect is assumed to be contained in this item's bounds. */virtualboolIsInvisibleInRect(constnsRect&aRect){returnfalse;}/** * Returns the result of GetBounds intersected with the item's clip. * The intersection is approximate since rounded corners are not taking into * account. */nsRectGetClippedBounds(nsDisplayListBuilder*aBuilder);nsRectGetBorderRect(){returnnsRect(ToReferenceFrame(),Frame()->GetSize());}nsRectGetPaddingRect(){returnFrame()->GetPaddingRectRelativeToSelf()+ToReferenceFrame();}nsRectGetContentRect(){returnFrame()->GetContentRectRelativeToSelf()+ToReferenceFrame();}/** * Checks if the frame(s) owning this display item have been marked as invalid, * and needing repainting. */virtualboolIsInvalid(nsRect&aRect){boolresult=mFrame?mFrame->IsInvalid(aRect):false;aRect+=ToReferenceFrame();returnresult;}/** * Creates and initializes an nsDisplayItemGeometry object that retains the current * areas covered by this display item. These need to retain enough information * such that they can be compared against a future nsDisplayItem of the same type, * and determine if repainting needs to happen. * * Subclasses wishing to store more information need to override both this * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry * subclass. * * The default implementation tracks both the display item bounds, and the frame's * border rect. */virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder){returnnewnsDisplayItemGenericGeometry(this,aBuilder);}/** * Compares an nsDisplayItemGeometry object from a previous paint against the * current item. Computes if the geometry of the item has changed, and the * invalidation area required for correct repainting. * * The existing geometry will have been created from a display item with a * matching GetPerFrameKey()/mFrame pair to the current item. * * The default implementation compares the display item bounds, and the frame's * border rect, and invalidates the entire bounds if either rect changes. * * @param aGeometry The geometry of the matching display item from the * previous paint. * @param aInvalidRegion Output param, the region to invalidate, or * unchanged if none. */virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion){constnsDisplayItemGenericGeometry*geometry=static_cast<constnsDisplayItemGenericGeometry*>(aGeometry);boolsnap;if(!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder,&snap))||!geometry->mBorderRect.IsEqualInterior(GetBorderRect())){aInvalidRegion->Or(GetBounds(aBuilder,&snap),geometry->mBounds);}}/** * An alternative default implementation of ComputeInvalidationRegion, * that instead invalidates only the changed area between the two items. */voidComputeInvalidationRegionDifference(nsDisplayListBuilder*aBuilder,constnsDisplayItemBoundsGeometry*aGeometry,nsRegion*aInvalidRegion){boolsnap;nsRectbounds=GetBounds(aBuilder,&snap);if(!aGeometry->mBounds.IsEqualInterior(bounds)){nscoordradii[8];if(aGeometry->mHasRoundedCorners||Frame()->GetBorderRadii(radii)){aInvalidRegion->Or(aGeometry->mBounds,bounds);}else{aInvalidRegion->Xor(aGeometry->mBounds,bounds);}}}/** * Called when the area rendered by this display item has changed (been * invalidated or changed geometry) since the last paint. This includes * when the display item was not rendered at all in the last paint. * It does NOT get called when a display item was being rendered and no * longer is, because generally that means there is no display item to * call this method on. */virtualvoidNotifyRenderingChanged(){}/** * @param aSnap set to true if the edges of the rectangles of the opaque * region would be snapped to device pixels when drawing * @return a region of the item that is opaque --- that is, every pixel * that is visible is painted with an opaque * color. This is useful for determining when one piece * of content completely obscures another so that we can do occlusion * culling. * This does not take clipping into account. */virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap){*aSnap=false;returnnsRegion();}/** * @return Some(nscolor) if the item is guaranteed to paint every pixel in its * bounds with the same (possibly translucent) color */virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder){returnmozilla::Nothing();}/** * @return true if the contents of this item are rendered fixed relative * to the nearest viewport. */virtualboolShouldFixToViewport(nsDisplayListBuilder*aBuilder){returnfalse;}virtualboolClearsBackground(){returnfalse;}virtualboolProvidesFontSmoothingBackgroundColor(nscolor*aColor){returnfalse;}/** * Returns true if all layers that can be active should be forced to be * active. Requires setting the pref layers.force-active=true. */staticboolForceActiveLayers();/** * @return LAYER_NONE if BuildLayer will return null. In this case * there is no layer for the item, and Paint should be called instead * to paint the content using Thebes. * Return LAYER_INACTIVE if there is a layer --- BuildLayer will * not return null (unless there's an error) --- but the layer contents * are not changing frequently. In this case it makes sense to composite * the layer into a PaintedLayer with other content, so we don't have to * recomposite it every time we paint. * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also, * all descendant display item frames must have an active scrolled root * that's either the same as this item's frame's active scrolled root, or * a descendant of this item's frame. This ensures that the entire * set of display items can be collapsed onto a single PaintedLayer. * Return LAYER_ACTIVE if the layer is active, that is, its contents are * changing frequently. In this case it makes sense to keep the layer * as a separate buffer in VRAM and composite it into the destination * every time we paint. * * Users of GetLayerState should check ForceActiveLayers() and if it returns * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE. */virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters){returnmozilla::LAYER_NONE;}/** * Return true to indicate the layer should be constructed even if it's * completely invisible. */virtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder){returnfalse;}/** * Actually paint this item to some rendering context. * Content outside mVisibleRect need not be painted. * aCtx must be set up as for nsDisplayList::Paint. */virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx){}#ifdef MOZ_DUMP_PAINTING/** * Mark this display item as being painted via FrameLayerBuilder::DrawPaintedLayer. */boolPainted(){returnmPainted;}/** * Check if this display item has been painted. */voidSetPainted(){mPainted=true;}#endif/** * Get the layer drawn by this display item. Call this only if * GetLayerState() returns something other than LAYER_NONE. * If GetLayerState returned LAYER_NONE then Paint will be called * instead. * This is called while aManager is in the construction phase. * * The caller (nsDisplayList) is responsible for setting the visible * region of the layer. * * @param aContainerParameters should be passed to * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is * constructed. */virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters){returnnullptr;}/** * Create the WebRenderCommands required to paint this display item. * The layer this item is in is passed in as rects must be relative * to their parent. */virtualvoidCreateWebRenderCommand(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,WebRenderDisplayItemLayer*aLayer){}/** * Alternate function to create the WebRenderCommands without * Layer. For layers mode, aManager->IsLayersFreeTransaction() * should be false to prevent doing GetLayerState again. For * layers-free mode, we should check if the layer state is * active first and have an early return if the layer state is * not active. * * @return true if successfully creating webrender commands. */virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder){returnfalse;}/** * Builds a DisplayItemLayer and sets the display item to this. */already_AddRefed<Layer>BuildDisplayItemLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters);/** * On entry, aVisibleRegion contains the region (relative to ReferenceFrame()) * which may be visible. If the display item opaquely covers an area, it * can remove that area from aVisibleRegion before returning. * nsDisplayList::ComputeVisibility automatically subtracts the region * returned by GetOpaqueRegion, and automatically removes items whose bounds * do not intersect the visible area, so implementations of * nsDisplayItem::ComputeVisibility do not need to do these things. * nsDisplayList::ComputeVisibility will already have set mVisibleRect on * this item to the intersection of *aVisibleRegion and this item's bounds. * We rely on that, so this should only be called by * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility. * aAllowVisibleRegionExpansion is a rect where we are allowed to * expand the visible region and is only used for making sure the * background behind a plugin is visible. * This method needs to be idempotent. * * @return true if the item is visible, false if no part of the item * is visible. */virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion);/** * Try to merge with the other item (which is below us in the display * list). This gets used by nsDisplayClip to coalesce clipping operations * (optimization), by nsDisplayOpacity to merge rendering for the same * content element into a single opacity group (correctness), and will be * used by nsDisplayOutline to merge multiple outlines for the same element * (also for correctness). * @return true if the merge was successful and the other item should be deleted */virtualboolTryMerge(nsDisplayItem*aItem){returnfalse;}/** * Appends the underlying frames of all display items that have been * merged into this one (excluding this item's own underlying frame) * to aFrames. */virtualvoidGetMergedFrames(nsTArray<nsIFrame*>*aFrames){}/** * During the visibility computation and after TryMerge, display lists may * return true here to flatten themselves away, removing them. This * flattening is distinctly different from FlattenTo, which occurs before * items are merged together. */virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder){returnfalse;}/** * If this has a child list where the children are in the same coordinate * system as this item (i.e., they have the same reference frame), * return the list. */virtualnsDisplayList*GetSameCoordinateSystemChildren(){returnnullptr;}virtualvoidUpdateBounds(nsDisplayListBuilder*aBuilder){}/** * Do UpdateBounds() for items with frames establishing or extending * 3D rendering context. * * This function is called by UpdateBoundsFor3D() of * nsDisplayTransform(), and it is called by * BuildDisplayListForStackingContext() on transform items * establishing 3D rendering context. * * The bounds of a transform item with the frame establishing 3D * rendering context should be computed by calling * DoUpdateBoundsPreserves3D() on all descendants that participate * the same 3d rendering context. */virtualvoidDoUpdateBoundsPreserves3D(nsDisplayListBuilder*aBuilder){}/** * If this has a child list, return it, even if the children are in * a different coordinate system to this item. */virtualnsDisplayList*GetChildren(){returnnullptr;}/** * Returns the visible rect. */constnsRect&GetVisibleRect()const{returnmVisibleRect;}/** * Returns the visible rect for the children, relative to their * reference frame. Can be different from mVisibleRect for nsDisplayTransform, * since the reference frame for the children is different from the reference * frame for the item itself. */virtualconstnsRect&GetVisibleRectForChildren()const{returnmVisibleRect;}/** * Stores the given opacity value to be applied when drawing. It is an error to * call this if CanApplyOpacity returned false. */virtualvoidApplyOpacity(nsDisplayListBuilder*aBuilder,floataOpacity,constDisplayItemClipChain*aClip){NS_ASSERTION(CanApplyOpacity(),"ApplyOpacity not supported on this type");}/** * Returns true if this display item would return true from ApplyOpacity without * actually applying the opacity. Otherwise returns false. */virtualboolCanApplyOpacity()const{returnfalse;}/** * For debugging and stuff */virtualconstchar*Name()=0;virtualvoidWriteDebugInfo(std::stringstream&aStream){}nsDisplayItem*GetAbove(){returnmAbove;}/** * Like ComputeVisibility, but does the work that nsDisplayList * does per-item: * -- Intersects GetBounds with aVisibleRegion and puts the result * in mVisibleRect * -- Subtracts bounds from aVisibleRegion if the item is opaque */boolRecomputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion);/** * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame()) */constnsPoint&ToReferenceFrame()const{NS_ASSERTION(mFrame,"No frame?");returnmToReferenceFrame;}/** * @return the root of the display list's frame (sub)tree, whose origin * establishes the coordinate system for the display list */constnsIFrame*ReferenceFrame()const{returnmReferenceFrame;}/** * Returns the reference frame for display item children of this item. */virtualconstnsIFrame*ReferenceFrameForChildren()const{returnmReferenceFrame;}AnimatedGeometryRoot*GetAnimatedGeometryRoot()const{MOZ_ASSERT(mAnimatedGeometryRoot,"Must have cached AGR before accessing it!");returnmAnimatedGeometryRoot;}virtualstructAnimatedGeometryRoot*AnimatedGeometryRootForScrollMetadata()const{returnGetAnimatedGeometryRoot();}/** * Checks if this display item (or any children) contains content that might * be rendered with component alpha (e.g. subpixel antialiasing). Returns the * bounds of the area that needs component alpha, or an empty rect if nothing * in the item does. */virtualnsRectGetComponentAlphaBounds(nsDisplayListBuilder*aBuilder){returnnsRect();}/** * Disable usage of component alpha. Currently only relevant for items that have text. */virtualvoidDisableComponentAlpha(){}/** * Check if we can add async animations to the layer for this display item. */virtualboolCanUseAsyncAnimations(nsDisplayListBuilder*aBuilder){returnfalse;}virtualboolSupportsOptimizingToImage(){returnfalse;}constDisplayItemClip&GetClip(){returnmClip?*mClip:DisplayItemClip::NoClip();}voidIntersectClip(nsDisplayListBuilder*aBuilder,constDisplayItemClipChain*aOther);voidSetActiveScrolledRoot(constActiveScrolledRoot*aActiveScrolledRoot){mActiveScrolledRoot=aActiveScrolledRoot;}constActiveScrolledRoot*GetActiveScrolledRoot()const{returnmActiveScrolledRoot;}virtualvoidSetClipChain(constDisplayItemClipChain*aClipChain);constDisplayItemClipChain*GetClipChain()const{returnmClipChain;}/** * Intersect all clips in our clip chain up to (and including) aASR and set * set the intersection as this item's clip. */voidFuseClipChainUpTo(nsDisplayListBuilder*aBuilder,constActiveScrolledRoot*aASR);boolBackfaceIsHidden(){returnmFrame->BackfaceIsHidden();}protected:friendclassnsDisplayList;nsDisplayItem(){mAbove=nullptr;}typedefbool(*PrefFunc)(void);boolShouldUseAdvancedLayer(LayerManager*aManager,PrefFuncaFunc);nsIFrame*mFrame;constDisplayItemClipChain*mClipChain;constDisplayItemClip*mClip;constActiveScrolledRoot*mActiveScrolledRoot;// Result of FindReferenceFrameFor(mFrame), if mFrame is non-nullconstnsIFrame*mReferenceFrame;structAnimatedGeometryRoot*mAnimatedGeometryRoot;// Result of ToReferenceFrame(mFrame), if mFrame is non-nullnsPointmToReferenceFrame;// This is the rectangle that needs to be painted.// Display item construction sets this to the dirty rect.// nsDisplayList::ComputeVisibility sets this to the visible region// of the item by intersecting the current visible region with the bounds// of the item. Paint implementations can use this to limit their drawing.// Guaranteed to be contained in GetBounds().nsRectmVisibleRect;boolmForceNotVisible;#ifdef MOZ_DUMP_PAINTING// True if this frame has been painted.boolmPainted;#endif};/** * Manages a singly-linked list of display list items. * * mSentinel is the sentinel list value, the first value in the null-terminated * linked list of items. mTop is the last item in the list (whose 'above' * pointer is null). This class has no virtual methods. So list objects are just * two pointers. * * Stepping upward through this list is very fast. Stepping downward is very * slow so we don't support it. The methods that need to step downward * (HitTest(), ComputeVisibility()) internally build a temporary array of all * the items while they do the downward traversal, so overall they're still * linear time. We have optimized for efficient AppendToTop() of both * items and lists, with minimal codesize. AppendToBottom() is efficient too. */classnsDisplayList{public:typedefmozilla::ActiveScrolledRootActiveScrolledRoot;typedefmozilla::layers::LayerLayer;typedefmozilla::layers::LayerManagerLayerManager;typedefmozilla::layers::PaintedLayerPaintedLayer;/** * Create an empty list. */nsDisplayList():mIsOpaque(false),mForceTransparentSurface(false){mTop=&mSentinel;mSentinel.mAbove=nullptr;}~nsDisplayList(){if(mSentinel.mAbove){NS_WARNING("Nonempty list left over?");}DeleteAll();}/** * Append an item to the top of the list. The item must not currently * be in a list and cannot be null. */voidAppendToTop(nsDisplayItem*aItem){NS_ASSERTION(aItem,"No item to append!");NS_ASSERTION(!aItem->mAbove,"Already in a list!");mTop->mAbove=aItem;mTop=aItem;}/** * Append a new item to the top of the list. The intended usage is * AppendNewToTop(new ...); */voidAppendNewToTop(nsDisplayItem*aItem){if(aItem){AppendToTop(aItem);}}/** * Append a new item to the bottom of the list. The intended usage is * AppendNewToBottom(new ...); */voidAppendNewToBottom(nsDisplayItem*aItem){if(aItem){AppendToBottom(aItem);}}/** * Append a new item to the bottom of the list. The item must be non-null * and not already in a list. */voidAppendToBottom(nsDisplayItem*aItem){NS_ASSERTION(aItem,"No item to append!");NS_ASSERTION(!aItem->mAbove,"Already in a list!");aItem->mAbove=mSentinel.mAbove;mSentinel.mAbove=aItem;if(mTop==&mSentinel){mTop=aItem;}}/** * Removes all items from aList and appends them to the top of this list */voidAppendToTop(nsDisplayList*aList){if(aList->mSentinel.mAbove){mTop->mAbove=aList->mSentinel.mAbove;mTop=aList->mTop;aList->mTop=&aList->mSentinel;aList->mSentinel.mAbove=nullptr;}}/** * Removes all items from aList and prepends them to the bottom of this list */voidAppendToBottom(nsDisplayList*aList){if(aList->mSentinel.mAbove){aList->mTop->mAbove=mSentinel.mAbove;mSentinel.mAbove=aList->mSentinel.mAbove;if(mTop==&mSentinel){mTop=aList->mTop;}aList->mTop=&aList->mSentinel;aList->mSentinel.mAbove=nullptr;}}/** * Remove an item from the bottom of the list and return it. */nsDisplayItem*RemoveBottom();/** * Remove all items from the list and call their destructors. */voidDeleteAll();/** * @return the item at the top of the list, or null if the list is empty */nsDisplayItem*GetTop()const{returnmTop!=&mSentinel?static_cast<nsDisplayItem*>(mTop):nullptr;}/** * @return the item at the bottom of the list, or null if the list is empty */nsDisplayItem*GetBottom()const{returnmSentinel.mAbove;}boolIsEmpty()const{returnmTop==&mSentinel;}/** * This is *linear time*! * @return the number of items in the list */uint32_tCount()const;/** * Stable sort the list by the z-order of GetUnderlyingFrame() on * each item. 'auto' is counted as zero. * It is assumed that the list is already in content document order. */voidSortByZOrder();/** * Stable sort the list by the tree order of the content of * GetUnderlyingFrame() on each item. z-index is ignored. * @param aCommonAncestor a common ancestor of all the content elements * associated with the display items, for speeding up tree order * checks, or nullptr if not known; it's only a hint, if it is not an * ancestor of some elements, then we lose performance but not correctness */voidSortByContentOrder(nsIContent*aCommonAncestor);/** * Sort the display list using a stable sort. Take care, because some of the * items might be nsDisplayLists themselves. * aComparator(Item item1, Item item2) should return true if item1 should go * before item2. * We sort the items into increasing order. */template<typenameItem,typenameComparator>voidSort(constComparator&aComparator){nsTArray<Item>items;while(nsDisplayItem*item=RemoveBottom()){items.AppendElement(Item(item));}std::stable_sort(items.begin(),items.end(),aComparator);for(Item&item:items){AppendToTop(item);}}/** * Compute visiblity for the items in the list. * We put this logic here so it can be shared by top-level * painting and also display items that maintain child lists. * This is also a good place to put ComputeVisibility-related logic * that must be applied to every display item. In particular, this * sets mVisibleRect on each display item. * This sets mIsOpaque if the entire visible area of this list has * been removed from aVisibleRegion when we return. * This does not remove any items from the list, so we can recompute * visiblity with different regions later (see * FrameLayerBuilder::DrawPaintedLayer). * This method needs to be idempotent. * * @param aVisibleRegion the area that is visible, relative to the * reference frame; on return, this contains the area visible under the list. * I.e., opaque contents of this list are subtracted from aVisibleRegion. * @param aListVisibleBounds must be equal to the bounds of the intersection * of aVisibleRegion and GetBounds() for this list. * @return true if any item in the list is visible. */boolComputeVisibilityForSublist(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion,constnsRect&aListVisibleBounds);/** * As ComputeVisibilityForSublist, but computes visibility for a root * list (a list that does not belong to an nsDisplayItem). * This method needs to be idempotent. * * @param aVisibleRegion the area that is visible */boolComputeVisibilityForRoot(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion);/** * Returns true if the visible region output from ComputeVisiblity was * empty, i.e. everything visible in this list is opaque. */boolIsOpaque()const{returnmIsOpaque;}/** * Returns true if any display item requires the surface to be transparent. */boolNeedsTransparentSurface()const{returnmForceTransparentSurface;}/** * Paint the list to the rendering context. We assume that (0,0) in aCtx * corresponds to the origin of the reference frame. For best results, * aCtx's current transform should make (0,0) pixel-aligned. The * rectangle in aDirtyRect is painted, which *must* be contained in the * dirty rect used to construct the display list. * * If aFlags contains PAINT_USE_WIDGET_LAYERS and * ShouldUseWidgetLayerManager() is set, then we will paint using * the reference frame's widget's layer manager (and ctx may be null), * otherwise we will use a temporary BasicLayerManager and ctx must * not be null. * * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's * layer manager has already had BeginTransaction() called on it and * we should not call it again. * * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode * to avoid short cut optimizations. * * This must only be called on the root display list of the display list * tree. * * We return the layer manager used for painting --- mainly so that * callers can dump its layer tree if necessary. */enum{PAINT_DEFAULT=0,PAINT_USE_WIDGET_LAYERS=0x01,PAINT_EXISTING_TRANSACTION=0x04,PAINT_NO_COMPOSITE=0x08,PAINT_COMPRESSED=0x10};already_AddRefed<LayerManager>PaintRoot(nsDisplayListBuilder*aBuilder,gfxContext*aCtx,uint32_taFlags);/** * Get the bounds. Takes the union of the bounds of all children. * The result is not cached. */nsRectGetBounds(nsDisplayListBuilder*aBuilder)const;/** * Get this list's bounds, respecting clips relative to aASR. The result is * the union of each item's clipped bounds with respect to aASR. That means * that if an item can move asynchronously with an ASR that is a descendant * of aASR, then the clipped bounds with respect to aASR will be the clip of * that item for aASR, because the item can move anywhere inside that clip. * If there is an item in this list which is not bounded with respect to * aASR (i.e. which does not have "finite bounds" with respect to aASR), * then this method trigger an assertion failure. */nsRectGetClippedBoundsWithRespectToASR(nsDisplayListBuilder*aBuilder,constActiveScrolledRoot*aASR)const;/** * Find the topmost display item that returns a non-null frame, and return * the frame. */voidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,nsDisplayItem::HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)const;/** * Compute the union of the visible rects of the items in the list. The * result is not cached. */nsRectGetVisibleRect()const;voidSetIsOpaque(){mIsOpaque=true;}voidSetNeedsTransparentSurface(){mForceTransparentSurface=true;}private:// This class is only used on stack, so we don't have to worry about leaking// it. Don't let us be heap-allocated!void*operatornew(size_tsz)CPP_THROW_NEW;nsDisplayItemLinkmSentinel;nsDisplayItemLink*mTop;// This is set to true by FrameLayerBuilder if the final visible region// is empty (i.e. everything that was visible is covered by some// opaque content in this list).boolmIsOpaque;// This is set to true by FrameLayerBuilder if any display item in this// list needs to force the surface containing this list to be transparent.boolmForceTransparentSurface;};/** * This is passed as a parameter to nsIFrame::BuildDisplayList. That method * will put any generated items onto the appropriate list given here. It's * basically just a collection with one list for each separate stacking layer. * The lists themselves are external to this object and thus can be shared * with others. Some of the list pointers may even refer to the same list. */classnsDisplayListSet{public:/** * @return a list where one should place the border and/or background for * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E) */nsDisplayList*BorderBackground()const{returnmBorderBackground;}/** * @return a list where one should place the borders and/or backgrounds for * block-level in-flow descendants (step 4 of CSS 2.1 appendix E) */nsDisplayList*BlockBorderBackgrounds()const{returnmBlockBorderBackgrounds;}/** * @return a list where one should place descendant floats (step 5 of * CSS 2.1 appendix E) */nsDisplayList*Floats()const{returnmFloats;}/** * @return a list where one should place the (pseudo) stacking contexts * for descendants of this frame (everything from steps 3, 7 and 8 * of CSS 2.1 appendix E) */nsDisplayList*PositionedDescendants()const{returnmPositioned;}/** * @return a list where one should place the outlines * for this frame and its descendants (step 9 of CSS 2.1 appendix E) */nsDisplayList*Outlines()const{returnmOutlines;}/** * @return a list where one should place all other content */nsDisplayList*Content()const{returnmContent;}nsDisplayListSet(nsDisplayList*aBorderBackground,nsDisplayList*aBlockBorderBackgrounds,nsDisplayList*aFloats,nsDisplayList*aContent,nsDisplayList*aPositionedDescendants,nsDisplayList*aOutlines):mBorderBackground(aBorderBackground),mBlockBorderBackgrounds(aBlockBorderBackgrounds),mFloats(aFloats),mContent(aContent),mPositioned(aPositionedDescendants),mOutlines(aOutlines){}/** * A copy constructor that lets the caller override the BorderBackground * list. */nsDisplayListSet(constnsDisplayListSet&aLists,nsDisplayList*aBorderBackground):mBorderBackground(aBorderBackground),mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),mFloats(aLists.Floats()),mContent(aLists.Content()),mPositioned(aLists.PositionedDescendants()),mOutlines(aLists.Outlines()){}/** * Move all display items in our lists to top of the corresponding lists in the * destination. */voidMoveTo(constnsDisplayListSet&aDestination)const;private:// This class is only used on stack, so we don't have to worry about leaking// it. Don't let us be heap-allocated!void*operatornew(size_tsz)CPP_THROW_NEW;protected:nsDisplayList*mBorderBackground;nsDisplayList*mBlockBorderBackgrounds;nsDisplayList*mFloats;nsDisplayList*mContent;nsDisplayList*mPositioned;nsDisplayList*mOutlines;};/** * A specialization of nsDisplayListSet where the lists are actually internal * to the object, and all distinct. */structnsDisplayListCollection:publicnsDisplayListSet{nsDisplayListCollection():nsDisplayListSet(&mLists[0],&mLists[1],&mLists[2],&mLists[3],&mLists[4],&mLists[5]){}explicitnsDisplayListCollection(nsDisplayList*aBorderBackground):nsDisplayListSet(aBorderBackground,&mLists[1],&mLists[2],&mLists[3],&mLists[4],&mLists[5]){}/** * Sort all lists by content order. */voidSortAllByContentOrder(nsIContent*aCommonAncestor){for(int32_ti=0;i<6;++i){mLists[i].SortByContentOrder(aCommonAncestor);}}private:// This class is only used on stack, so we don't have to worry about leaking// it. Don't let us be heap-allocated!void*operatornew(size_tsz)CPP_THROW_NEW;nsDisplayListmLists[6];};classnsDisplayImageContainer:publicnsDisplayItem{public:typedefmozilla::LayerIntPointLayerIntPoint;typedefmozilla::LayoutDeviceRectLayoutDeviceRect;typedefmozilla::layers::ImageContainerImageContainer;typedefmozilla::layers::ImageLayerImageLayer;nsDisplayImageContainer(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){}/** * @return true if this display item can be optimized into an image layer. * It is an error to call GetContainer() unless you've called * CanOptimizeToImageLayer() first and it returned true. */virtualboolCanOptimizeToImageLayer(LayerManager*aManager,nsDisplayListBuilder*aBuilder);already_AddRefed<ImageContainer>GetContainer(LayerManager*aManager,nsDisplayListBuilder*aBuilder);voidConfigureLayer(ImageLayer*aLayer,constContainerLayerParameters&aParameters);virtualalready_AddRefed<imgIContainer>GetImage()=0;virtualnsRectGetDestRect()=0;virtualboolSupportsOptimizingToImage()override{returntrue;}};/** * Use this class to implement not-very-frequently-used display items * that are not opaque, do not receive events, and are bounded by a frame's * border-rect. * * This should not be used for display items which are created frequently, * because each item is one or two pointers bigger than an item from a * custom display item class could be, and fractionally slower. However it does * save code size. We use this for infrequently-used item types. */classnsDisplayGeneric:publicnsDisplayItem{public:typedefvoid(*PaintCallback)(nsIFrame*aFrame,DrawTarget*aDrawTarget,constnsRect&aDirtyRect,nsPointaFramePt);// XXX: should be removed eventuallytypedefvoid(*OldPaintCallback)(nsIFrame*aFrame,gfxContext*aCtx,constnsRect&aDirtyRect,nsPointaFramePt);nsDisplayGeneric(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,PaintCallbackaPaint,constchar*aName,TypeaType):nsDisplayItem(aBuilder,aFrame),mPaint(aPaint),mOldPaint(nullptr),mName(aName),mType(aType){MOZ_COUNT_CTOR(nsDisplayGeneric);}// XXX: should be removed eventuallynsDisplayGeneric(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,OldPaintCallbackaOldPaint,constchar*aName,TypeaType):nsDisplayItem(aBuilder,aFrame),mPaint(nullptr),mOldPaint(aOldPaint),mName(aName),mType(aType){MOZ_COUNT_CTOR(nsDisplayGeneric);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayGeneric(){MOZ_COUNT_DTOR(nsDisplayGeneric);}#endifvirtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override{MOZ_ASSERT(!!mPaint!=!!mOldPaint);if(mPaint){mPaint(mFrame,aCtx->GetDrawTarget(),mVisibleRect,ToReferenceFrame());}else{mOldPaint(mFrame,aCtx,mVisibleRect,ToReferenceFrame());}}NS_DISPLAY_DECL_NAME(mName,mType)protected:PaintCallbackmPaint;OldPaintCallbackmOldPaint;// XXX: should be removed eventuallyconstchar*mName;TypemType;};#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)/** * This class implements painting of reflow counts. Ideally, we would simply * make all the frame names be those returned by nsFrame::GetFrameName * (except that tosses in the content tag name!) and support only one color * and eliminate this class altogether in favor of nsDisplayGeneric, but for * the time being we can't pass args to a PaintCallback, so just have a * separate class to do the right thing. Sadly, this alsmo means we need to * hack all leaf frame classes to handle this. * * XXXbz the color thing is a bit of a mess, but 0 basically means "not set" * here... I could switch it all to nscolor, but why bother? */classnsDisplayReflowCount:publicnsDisplayItem{public:nsDisplayReflowCount(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constchar*aFrameName,uint32_taColor=0):nsDisplayItem(aBuilder,aFrame),mFrameName(aFrameName),mColor(aColor){MOZ_COUNT_CTOR(nsDisplayReflowCount);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayReflowCount(){MOZ_COUNT_DTOR(nsDisplayReflowCount);}#endifvirtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override{mFrame->PresContext()->PresShell()->PaintCount(mFrameName,aCtx,mFrame->PresContext(),mFrame,ToReferenceFrame(),mColor);}NS_DISPLAY_DECL_NAME("nsDisplayReflowCount",TYPE_REFLOW_COUNT)protected:constchar*mFrameName;nscolormColor;};#define DO_GLOBAL_REFLOW_COUNT_DSP(_name) \ PR_BEGIN_MACRO \ if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \ PresContext()->PresShell()->IsPaintingFrameCounts()) { \ aLists.Outlines()->AppendNewToTop( \ new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name)); \ } \ PR_END_MACRO#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color) \ PR_BEGIN_MACRO \ if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \ PresContext()->PresShell()->IsPaintingFrameCounts()) { \ aLists.Outlines()->AppendNewToTop( \ new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \ } \ PR_END_MACRO/* Macro to be used for classes that don't actually implement BuildDisplayList */#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super) \ void BuildDisplayList(nsDisplayListBuilder* aBuilder, \ const nsRect& aDirtyRect, \ const nsDisplayListSet& aLists) { \ DO_GLOBAL_REFLOW_COUNT_DSP(#_class); \ _super::BuildDisplayList(aBuilder, aDirtyRect, aLists); \ }#else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF#define DO_GLOBAL_REFLOW_COUNT_DSP(_name)#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)#endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERFclassnsDisplayCaret:publicnsDisplayItem{public:nsDisplayCaret(nsDisplayListBuilder*aBuilder,nsIFrame*aCaretFrame);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayCaret();#endifvirtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;NS_DISPLAY_DECL_NAME("Caret",TYPE_CARET)virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;protected:RefPtr<nsCaret>mCaret;nsRectmBounds;};/** * The standard display item to paint the CSS borders of a frame. */classnsDisplayBorder:publicnsDisplayItem{public:nsDisplayBorder(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayBorder(){MOZ_COUNT_DTOR(nsDisplayBorder);}#endifvirtualboolIsInvisibleInRect(constnsRect&aRect)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;NS_DISPLAY_DECL_NAME("Border",TYPE_BORDER)virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override;virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;virtualnsRegionGetTightBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=true;returnCalculateBounds(*mFrame->StyleBorder());}protected:voidCreateBorderImageWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,WebRenderDisplayItemLayer*aLayer);nsRegionCalculateBounds(constnsStyleBorder&aStyleBorder);mozilla::Array<mozilla::gfx::Color,4>mColors;mozilla::Array<mozilla::LayerCoord,4>mWidths;mozilla::Array<mozilla::LayerSize,4>mCorners;mozilla::Array<uint8_t,4>mBorderStyles;mozilla::LayerRectmRect;mozilla::Maybe<nsCSSBorderRenderer>mBorderRenderer;mozilla::Maybe<nsCSSBorderImageRenderer>mBorderImageRenderer;nsRectmBounds;};/** * A simple display item that just renders a solid color across the * specified bounds. For canvas frames (in the CSS sense) we split off the * drawing of the background color into this class (from nsDisplayBackground * via nsDisplayCanvasBackground). This is done so that we can always draw a * background color to avoid ugly flashes of white when we can't draw a full * frame tree (ie when a page is loading). The bounds can differ from the * frame's bounds -- this is needed when a frame/iframe is loading and there * is not yet a frame tree to go in the frame/iframe so we use the subdoc * frame of the parent document as a standin. */classnsDisplaySolidColorBase:publicnsDisplayItem{public:nsDisplaySolidColorBase(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nscoloraColor):nsDisplayItem(aBuilder,aFrame),mColor(aColor){}virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplaySolidColorGeometry(this,aBuilder,mColor);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{constnsDisplaySolidColorGeometry*geometry=static_cast<constnsDisplaySolidColorGeometry*>(aGeometry);if(mColor!=geometry->mColor){booldummy;aInvalidRegion->Or(geometry->mBounds,GetBounds(aBuilder,&dummy));return;}ComputeInvalidationRegionDifference(aBuilder,geometry,aInvalidRegion);}virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=false;nsRegionresult;if(NS_GET_A(mColor)==255){result=GetBounds(aBuilder,aSnap);}returnresult;}virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override{returnmozilla::Some(mColor);}protected:nscolormColor;};classnsDisplaySolidColor:publicnsDisplaySolidColorBase{public:nsDisplaySolidColor(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRect&aBounds,nscoloraColor):nsDisplaySolidColorBase(aBuilder,aFrame,aColor),mBounds(aBounds){NS_ASSERTION(NS_GET_A(aColor)>0,"Don't create invisible nsDisplaySolidColors!");MOZ_COUNT_CTOR(nsDisplaySolidColor);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplaySolidColor(){MOZ_COUNT_DTOR(nsDisplaySolidColor);}#endifvirtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualvoidWriteDebugInfo(std::stringstream&aStream)override;NS_DISPLAY_DECL_NAME("SolidColor",TYPE_SOLID_COLOR)private:nsRectmBounds;};/** * A display item that renders a solid color over a region. This is not * exposed through CSS, its only purpose is efficient invalidation of * the find bar highlighter dimmer. */classnsDisplaySolidColorRegion:publicnsDisplayItem{typedefmozilla::gfx::ColorColor;public:nsDisplaySolidColorRegion(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRegion&aRegion,nscoloraColor):nsDisplayItem(aBuilder,aFrame),mRegion(aRegion),mColor(Color::FromABGR(aColor)){NS_ASSERTION(NS_GET_A(aColor)>0,"Don't create invisible nsDisplaySolidColorRegions!");MOZ_COUNT_CTOR(nsDisplaySolidColorRegion);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplaySolidColorRegion(){MOZ_COUNT_DTOR(nsDisplaySolidColorRegion);}#endifvirtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplaySolidColorRegionGeometry(this,aBuilder,mRegion,mColor);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{constnsDisplaySolidColorRegionGeometry*geometry=static_cast<constnsDisplaySolidColorRegionGeometry*>(aGeometry);if(mColor==geometry->mColor){aInvalidRegion->Xor(geometry->mRegion,mRegion);}else{aInvalidRegion->Or(geometry->mRegion.GetBounds(),mRegion.GetBounds());}}protected:virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualvoidWriteDebugInfo(std::stringstream&aStream)override;NS_DISPLAY_DECL_NAME("SolidColorRegion",TYPE_SOLID_COLOR_REGION)private:nsRegionmRegion;ColormColor;};/** * A display item to paint one background-image for a frame. Each background * image layer gets its own nsDisplayBackgroundImage. */classnsDisplayBackgroundImage:publicnsDisplayImageContainer{public:typedefmozilla::StyleGeometryBoxStyleGeometryBox;structInitData{nsDisplayListBuilder*builder;nsIFrame*frame;constnsStyleBackground*backgroundStyle;nsCOMPtr<imgIContainer>image;nsRectbackgroundRect;nsRectfillArea;nsRectdestArea;uint32_tlayer;boolisRasterImage;boolshouldFixToViewport;};/** * aLayer signifies which background layer this item represents. * aIsThemed should be the value of aFrame->IsThemed. * aBackgroundStyle should be the result of * nsCSSRendering::FindBackground, or null if FindBackground returned false. * aBackgroundRect is relative to aFrame. */enumclassLayerizeFixed:uint8_t{ALWAYS_LAYERIZE_FIXED_BACKGROUND,DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS};staticInitDataGetInitData(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,uint32_taLayer,constnsRect&aBackgroundRect,constnsStyleBackground*aBackgroundStyle,LayerizeFixedaLayerizeFixed);explicitnsDisplayBackgroundImage(constInitData&aInitData);virtual~nsDisplayBackgroundImage();// This will create and append new items for all the layers of the// background. Returns whether we appended a themed background.// aAllowWillPaintBorderOptimization should usually be left at true, unless// aFrame has special border drawing that causes opaque borders to not// actually be opaque.staticboolAppendBackgroundItemsToTop(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRect&aBackgroundRect,nsDisplayList*aList,boolaAllowWillPaintBorderOptimization=true,nsStyleContext*aStyleContext=nullptr,constnsRect&aBackgroundOriginRect=nsRect(),nsIFrame*aSecondaryReferenceFrame=nullptr);virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualvoidCreateWebRenderCommand(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,WebRenderDisplayItemLayer*aLayer)override;virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override;/** * GetBounds() returns the background painting area. */virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualuint32_tGetPerFrameKey()override;NS_DISPLAY_DECL_NAME("Background",TYPE_BACKGROUND)/** * Return the background positioning area. * (GetBounds() returns the background painting area.) * Can be called only when mBackgroundStyle is non-null. */nsRectGetPositioningArea();/** * Returns true if existing rendered pixels of this display item may need * to be redrawn if the positioning area size changes but its position does * not. * If false, only the changed painting area needs to be redrawn when the * positioning area size changes but its position does not. */boolRenderingMightDependOnPositioningAreaSizeChange();virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayBackgroundGeometry(this,aBuilder);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;virtualboolCanOptimizeToImageLayer(LayerManager*aManager,nsDisplayListBuilder*aBuilder)override;virtualalready_AddRefed<imgIContainer>GetImage()override;virtualnsRectGetDestRect()override;staticnsRegionGetInsideClipRegion(nsDisplayItem*aItem,StyleGeometryBoxaClip,constnsRect&aRect,constnsRect&aBackgroundRect);virtualboolShouldFixToViewport(nsDisplayListBuilder*aBuilder)override{returnmShouldFixToViewport;}protected:typedefclassmozilla::layers::ImageContainerImageContainer;typedefclassmozilla::layers::ImageLayerImageLayer;boolCanBuildWebRenderDisplayItems(LayerManager*aManager);boolTryOptimizeToImageLayer(LayerManager*aManager,nsDisplayListBuilder*aBuilder);nsRectGetBoundsInternal(nsDisplayListBuilder*aBuilder);voidPaintInternal(nsDisplayListBuilder*aBuilder,gfxContext*aCtx,constnsRect&aBounds,nsRect*aClipRect);virtualnsIFrame*StyleFrame(){returnmFrame;}// Determine whether we want to be separated into our own layer, independent// of whether this item can actually be layerized.enumImageLayerization{WHENEVER_POSSIBLE,ONLY_FOR_SCALING,NO_LAYER_NEEDED};ImageLayerizationShouldCreateOwnLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager);// Cache the result of nsCSSRendering::FindBackground. Always null if// mIsThemed is true or if FindBackground returned false.constnsStyleBackground*mBackgroundStyle;nsCOMPtr<imgIContainer>mImage;nsRectmBackgroundRect;// relative to the reference framensRectmFillRect;nsRectmDestRect;/* Bounds of this display item */nsRectmBounds;uint32_tmLayer;boolmIsRasterImage;/* Whether the image should be treated as fixed to the viewport. */boolmShouldFixToViewport;uint32_tmImageFlags;};enumclassTableType:uint8_t{TABLE,TABLE_COL,TABLE_COL_GROUP,TABLE_ROW,TABLE_ROW_GROUP,TABLE_CELL,TABLE_TYPE_MAX};enumclassTableTypeBits:uint8_t{COUNT=3};static_assert(static_cast<uint8_t>(TableType::TABLE_TYPE_MAX)<(1<<(static_cast<uint8_t>(TableTypeBits::COUNT)+1)),"TableType cannot fit with TableTypeBits::COUNT");TableTypeGetTableTypeFromFrame(nsIFrame*aFrame);/** * A display item to paint background image for table. For table parts, such * as row, row group, col, col group, when drawing its background, we'll * create separate background image display item for its containning cell. * Those background image display items will reference to same DisplayItemData * if we keep the mFrame point to cell's ancestor frame. We don't want to this * happened bacause share same DisplatItemData will cause many bugs. So that * we let mFrame point to cell frame and store the table type of the ancestor * frame. And use mFrame and table type as key to generate DisplayItemData to * avoid sharing DisplayItemData. * * Also store ancestor frame as mStyleFrame for all rendering informations. */classnsDisplayTableBackgroundImage:publicnsDisplayBackgroundImage{public:nsDisplayTableBackgroundImage(constInitData&aInitData,nsIFrame*aCellFrame);virtualuint32_tGetPerFrameKey()override{return(static_cast<uint8_t>(mTableType)<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}virtualboolIsInvalid(nsRect&aRect)override;protected:virtualnsIFrame*StyleFrame()override{returnmStyleFrame;}nsIFrame*mStyleFrame;TableTypemTableType;};/** * A display item to paint the native theme background for a frame. */classnsDisplayThemedBackground:publicnsDisplayItem{public:nsDisplayThemedBackground(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRect&aBackgroundRect);virtual~nsDisplayThemedBackground();virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override;virtualboolProvidesFontSmoothingBackgroundColor(nscolor*aColor)override;/** * GetBounds() returns the background painting area. */virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;NS_DISPLAY_DECL_NAME("ThemedBackground",TYPE_THEMED_BACKGROUND)/** * Return the background positioning area. * (GetBounds() returns the background painting area.) * Can be called only when mBackgroundStyle is non-null. */nsRectGetPositioningArea();/** * Return whether our frame's document does not have the state * NS_DOCUMENT_STATE_WINDOW_INACTIVE. */boolIsWindowActive();virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayThemedBackgroundGeometry(this,aBuilder);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;virtualvoidWriteDebugInfo(std::stringstream&aStream)override;protected:nsRectGetBoundsInternal();voidPaintInternal(nsDisplayListBuilder*aBuilder,gfxContext*aCtx,constnsRect&aBounds,nsRect*aClipRect);nsRectmBackgroundRect;nsRectmBounds;nsITheme::TransparencymThemeTransparency;uint8_tmAppearance;};classnsDisplayBackgroundColor:publicnsDisplayItem{typedefmozilla::gfx::ColorColor;public:nsDisplayBackgroundColor(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRect&aBackgroundRect,constnsStyleBackground*aBackgroundStyle,nscoloraColor):nsDisplayItem(aBuilder,aFrame),mBackgroundRect(aBackgroundRect),mBackgroundStyle(aBackgroundStyle),mColor(Color::FromABGR(aColor)){}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override;virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualvoidApplyOpacity(nsDisplayListBuilder*aBuilder,floataOpacity,constDisplayItemClipChain*aClip)override;virtualboolCanApplyOpacity()constoverride;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=true;returnmBackgroundRect;}virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplaySolidColorGeometry(this,aBuilder,mColor.ToABGR());}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{constnsDisplaySolidColorGeometry*geometry=static_cast<constnsDisplaySolidColorGeometry*>(aGeometry);if(mColor.ToABGR()!=geometry->mColor){booldummy;aInvalidRegion->Or(geometry->mBounds,GetBounds(aBuilder,&dummy));return;}ComputeInvalidationRegionDifference(aBuilder,geometry,aInvalidRegion);}NS_DISPLAY_DECL_NAME("BackgroundColor",TYPE_BACKGROUND_COLOR)virtualvoidWriteDebugInfo(std::stringstream&aStream)override;protected:constnsRectmBackgroundRect;constnsStyleBackground*mBackgroundStyle;mozilla::gfx::ColormColor;};classnsDisplayTableBackgroundColor:publicnsDisplayBackgroundColor{public:nsDisplayTableBackgroundColor(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsRect&aBackgroundRect,constnsStyleBackground*aBackgroundStyle,nscoloraColor,nsIFrame*aAncestorFrame):nsDisplayBackgroundColor(aBuilder,aFrame,aBackgroundRect,aBackgroundStyle,aColor),mTableType(GetTableTypeFromFrame(aAncestorFrame)){}virtualuint32_tGetPerFrameKey()override{return(static_cast<uint8_t>(mTableType)<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}protected:TableTypemTableType;};classnsDisplayClearBackground:publicnsDisplayItem{public:nsDisplayClearBackground(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){}virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=true;returnnsRect(ToReferenceFrame(),Frame()->GetSize());}virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=false;returnGetBounds(aBuilder,aSnap);}virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override{returnmozilla::Some(NS_RGBA(0,0,0,0));}virtualboolClearsBackground()override{returntrue;}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override{returnmozilla::LAYER_ACTIVE_FORCE;}virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;NS_DISPLAY_DECL_NAME("ClearBackground",TYPE_CLEAR_BACKGROUND)};/** * The standard display item to paint the outer CSS box-shadows of a frame. */classnsDisplayBoxShadowOuterfinal:publicnsDisplayItem{public:nsDisplayBoxShadowOuter(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame),mOpacity(1.0){MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);mBounds=GetBoundsInternal();}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayBoxShadowOuter(){MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);}#endifvirtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualboolIsInvisibleInRect(constnsRect&aRect)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;NS_DISPLAY_DECL_NAME("BoxShadowOuter",TYPE_BOX_SHADOW_OUTER)virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;virtualvoidApplyOpacity(nsDisplayListBuilder*aBuilder,floataOpacity,constDisplayItemClipChain*aClip)override{NS_ASSERTION(CanApplyOpacity(),"ApplyOpacity should be allowed");mOpacity=aOpacity;IntersectClip(aBuilder,aClip);}virtualboolCanApplyOpacity()constoverride{returntrue;}virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayBoxShadowOuterGeometry(this,aBuilder,mOpacity);}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;boolCanBuildWebRenderDisplayItems();virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;nsRectGetBoundsInternal();private:nsRegionmVisibleRegion;nsRectmBounds;floatmOpacity;};/** * The standard display item to paint the inner CSS box-shadows of a frame. */classnsDisplayBoxShadowInner:publicnsDisplayItem{public:nsDisplayBoxShadowInner(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayBoxShadowInner(){MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);}#endifvirtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;NS_DISPLAY_DECL_NAME("BoxShadowInner",TYPE_BOX_SHADOW_INNER)virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayBoxShadowInnerGeometry(this,aBuilder);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{constnsDisplayBoxShadowInnerGeometry*geometry=static_cast<constnsDisplayBoxShadowInnerGeometry*>(aGeometry);if(!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())){// nsDisplayBoxShadowInner is based around the padding rect, but it can// touch pixels outside of this. We should invalidate the entire bounds.boolsnap;aInvalidRegion->Or(geometry->mBounds,GetBounds(aBuilder,&snap));}}staticboolCanCreateWebRenderCommands(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsPointaReferencePoint);staticvoidCreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsRegion&aVisibleRegion,nsIFrame*aFrame,constnsRectaBorderRect);virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;private:nsRegionmVisibleRegion;};/** * The standard display item to paint the CSS outline of a frame. */classnsDisplayOutline:publicnsDisplayItem{public:nsDisplayOutline(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){MOZ_COUNT_CTOR(nsDisplayOutline);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayOutline(){MOZ_COUNT_DTOR(nsDisplayOutline);}#endifvirtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;virtualboolIsInvisibleInRect(constnsRect&aRect)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;NS_DISPLAY_DECL_NAME("Outline",TYPE_OUTLINE)mozilla::Maybe<nsCSSBorderRenderer>mBorderRenderer;};/** * A class that lets you receive events within the frame bounds but never paints. */classnsDisplayEventReceiver:publicnsDisplayItem{public:nsDisplayEventReceiver(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){MOZ_COUNT_CTOR(nsDisplayEventReceiver);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayEventReceiver(){MOZ_COUNT_DTOR(nsDisplayEventReceiver);}#endifvirtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;NS_DISPLAY_DECL_NAME("EventReceiver",TYPE_EVENT_RECEIVER)};/** * A display item that tracks event-sensitive regions which will be set * on the ContainerLayer that eventually contains this item. * * One of these is created for each stacking context and pseudo-stacking-context. * It accumulates regions for event targets contributed by the border-boxes of * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions * eventually contributes its regions to the PaintedLayer it is placed in by * FrameLayerBuilder. (We don't create a display item for every frame that * could be an event target (i.e. almost all frames), because that would be * high overhead.) * * We always make leaf layers other than PaintedLayers transparent to events. * For example, an event targeting a canvas or video will actually target the * background of that element, which is logically in the PaintedLayer behind the * CanvasFrame or ImageFrame. We only need to create a * nsDisplayLayerEventRegions when an element's background could be in front * of a lower z-order element with its own layer. */classnsDisplayLayerEventRegionsfinal:publicnsDisplayItem{public:nsDisplayLayerEventRegions(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame){MOZ_COUNT_CTOR(nsDisplayLayerEventRegions);}#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayLayerEventRegions(){MOZ_COUNT_DTOR(nsDisplayLayerEventRegions);}#endifvirtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=false;returnnsRect();}nsRectGetHitRegionBounds(nsDisplayListBuilder*aBuilder,bool*aSnap){*aSnap=false;returnmHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds());}virtualvoidApplyOpacity(nsDisplayListBuilder*aBuilder,floataOpacity,constDisplayItemClipChain*aClip)override{NS_ASSERTION(CanApplyOpacity(),"ApplyOpacity should be allowed");}virtualboolCanApplyOpacity()constoverride{returntrue;}NS_DISPLAY_DECL_NAME("LayerEventRegions",TYPE_LAYER_EVENT_REGIONS)// Indicate that aFrame's border-box contributes to the event regions for// this layer. aFrame must have the same reference frame as mFrame.voidAddFrame(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame);// Indicate that an inactive scrollframe's scrollport should be added to the// dispatch-to-content region, to ensure that APZ lets content create a// displayport.voidAddInactiveScrollPort(constnsRect&aRect);boolIsEmpty()const;int32_tZIndex()constoverride;voidSetOverrideZIndex(int32_taZIndex);constnsRegion&HitRegion(){returnmHitRegion;}constnsRegion&MaybeHitRegion(){returnmMaybeHitRegion;}constnsRegion&DispatchToContentHitRegion(){returnmDispatchToContentHitRegion;}constnsRegion&NoActionRegion(){returnmNoActionRegion;}constnsRegion&HorizontalPanRegion(){returnmHorizontalPanRegion;}constnsRegion&VerticalPanRegion(){returnmVerticalPanRegion;}nsRegionCombinedTouchActionRegion();virtualvoidWriteDebugInfo(std::stringstream&aStream)override;private:// Relative to aFrame's reference frame.// These are the points that are definitely in the hit region.nsRegionmHitRegion;// These are points that may or may not be in the hit region. Only main-thread// event handling can tell for sure (e.g. because complex shapes are present).nsRegionmMaybeHitRegion;// These are points that need to be dispatched to the content thread for// resolution. Always contained in the union of mHitRegion and mMaybeHitRegion.nsRegionmDispatchToContentHitRegion;// These are points where panning is disabled, as determined by the touch-action// property. Always contained in the union of mHitRegion and mMaybeHitRegion.nsRegionmNoActionRegion;// These are points where panning is horizontal, as determined by the touch-action// property. Always contained in the union of mHitRegion and mMaybeHitRegion.nsRegionmHorizontalPanRegion;// These are points where panning is vertical, as determined by the touch-action// property. Always contained in the union of mHitRegion and mMaybeHitRegion.nsRegionmVerticalPanRegion;// If these event regions are for an inactive scroll frame, the z-index of// this display item is overridden to be the largest z-index of the content// in the scroll frame. This ensures that the event regions item remains on// top of the content after sorting items by z-index.mozilla::Maybe<int32_t>mOverrideZIndex;};/** * A class that lets you wrap a display list as a display item. * * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped * list has many items, it's not clear which one has the 'underlying frame'. * Thus we force the creator to specify what the underlying frame is. The * underlying frame should be the root of a stacking context, because sorting * a list containing this item will not get at the children. * * In some cases (e.g., clipping) we want to wrap a list but we don't have a * particular underlying frame that is a stacking context root. In that case * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must * detect and handle this case. */classnsDisplayWrapList:publicnsDisplayItem{public:/** * Takes all the items from aList and puts them in our list. */nsDisplayWrapList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList);nsDisplayWrapList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot);nsDisplayWrapList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayItem*aItem);nsDisplayWrapList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame),mOverrideZIndex(0),mHasZIndexOverride(false){MOZ_COUNT_CTOR(nsDisplayWrapList);mBaseVisibleRect=mVisibleRect;}virtual~nsDisplayWrapList();/** * Call this if the wrapped list is changed. */virtualvoidUpdateBounds(nsDisplayListBuilder*aBuilder)override{mBounds=mList.GetClippedBoundsWithRespectToASR(aBuilder,mActiveScrolledRoot);// The display list may contain content that's visible outside the visible// rect (i.e. the current dirty rect) passed in when the item was created.// This happens when the dirty rect has been restricted to the visual// overflow rect of a frame for some reason (e.g. when setting up dirty// rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that// frame contains placeholders for out-of-flows that aren't descendants of// the frame.mVisibleRect.UnionRect(mBaseVisibleRect,mList.GetVisibleRect());}virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override;virtualvoidPaint(nsDisplayListBuilder*aBuilder,gfxContext*aCtx)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualboolTryMerge(nsDisplayItem*aItem)override{returnfalse;}virtualvoidGetMergedFrames(nsTArray<nsIFrame*>*aFrames)override{aFrames->AppendElements(mMergedFrames);}virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returntrue;}virtualboolIsInvalid(nsRect&aRect)override{if(mFrame->IsInvalid(aRect)&&aRect.IsEmpty()){returntrue;}nsRecttemp;for(uint32_ti=0;i<mMergedFrames.Length();i++){if(mMergedFrames[i]->IsInvalid(temp)&&temp.IsEmpty()){aRect.SetEmpty();returntrue;}aRect=aRect.Union(temp);}aRect+=ToReferenceFrame();return!aRect.IsEmpty();}NS_DISPLAY_DECL_NAME("WrapList",TYPE_WRAP_LIST)virtualnsRectGetComponentAlphaBounds(nsDisplayListBuilder*aBuilder)override;virtualnsDisplayList*GetSameCoordinateSystemChildren()override{NS_ASSERTION(mList.IsEmpty()||!ReferenceFrame()||!mList.GetBottom()->ReferenceFrame()||mList.GetBottom()->ReferenceFrame()==ReferenceFrame(),"Children must have same reference frame");return&mList;}virtualnsDisplayList*GetChildren()override{return&mList;}virtualint32_tZIndex()constoverride{return(mHasZIndexOverride)?mOverrideZIndex:nsDisplayItem::ZIndex();}voidSetOverrideZIndex(int32_taZIndex){mHasZIndexOverride=true;mOverrideZIndex=aZIndex;}voidSetVisibleRect(constnsRect&aRect);voidSetReferenceFrame(constnsIFrame*aFrame);/** * This creates a copy of this item, but wrapping aItem instead of * our existing list. Only gets called if this item returned nullptr * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from * GetUnderlyingFrame(). */virtualnsDisplayWrapList*WrapWithClone(nsDisplayListBuilder*aBuilder,nsDisplayItem*aItem){NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!");returnnullptr;}protected:nsDisplayWrapList(){}voidMergeFromTrackingMergedFrames(nsDisplayWrapList*aOther){mList.AppendToBottom(&aOther->mList);mBounds.UnionRect(mBounds,aOther->mBounds);mVisibleRect.UnionRect(mVisibleRect,aOther->mVisibleRect);mMergedFrames.AppendElement(aOther->mFrame);mMergedFrames.AppendElements(mozilla::Move(aOther->mMergedFrames));}nsDisplayListmList;// The frames from items that have been merged into this item, excluding// this item's own frame.nsTArray<nsIFrame*>mMergedFrames;nsRectmBounds;// Visible rect contributed by this display item itself.// Our mVisibleRect may include the visible areas of children.nsRectmBaseVisibleRect;int32_tmOverrideZIndex;boolmHasZIndexOverride;};/** * We call WrapDisplayList on the in-flow lists: BorderBackground(), * BlockBorderBackgrounds() and Content(). * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(), * and Floats(). This is done to support special wrapping processing for frames * that may not be in-flow descendants of the current frame. */classnsDisplayWrapper{public:// This is never instantiated directly (it has pure virtual methods), so no// need to count constructors and destructors.virtualboolWrapBorderBackground(){returntrue;}virtualnsDisplayItem*WrapList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList)=0;virtualnsDisplayItem*WrapItem(nsDisplayListBuilder*aBuilder,nsDisplayItem*aItem)=0;nsresultWrapLists(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsDisplayListSet&aIn,constnsDisplayListSet&aOut);nsresultWrapListsInPlace(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,constnsDisplayListSet&aLists);protected:nsDisplayWrapper(){}};/** * The standard display item to paint a stacking context with translucency * set by the stacking context root frame's 'opacity' style. */classnsDisplayOpacity:publicnsDisplayWrapList{public:nsDisplayOpacity(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot,boolaForEventsAndPluginsOnly);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayOpacity();#endifvirtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualboolTryMerge(nsDisplayItem*aItem)override;virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{// We don't need to compute an invalidation region since we have LayerTreeInvalidation}virtualboolIsInvalid(nsRect&aRect)override{if(mForEventsAndPluginsOnly){returnfalse;}returnnsDisplayWrapList::IsInvalid(aRect);}virtualvoidApplyOpacity(nsDisplayListBuilder*aBuilder,floataOpacity,constDisplayItemClipChain*aClip)override;virtualboolCanApplyOpacity()constoverride;virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override;staticboolNeedsActiveLayer(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame);NS_DISPLAY_DECL_NAME("Opacity",TYPE_OPACITY)virtualvoidWriteDebugInfo(std::stringstream&aStream)override;boolCanUseAsyncAnimations(nsDisplayListBuilder*aBuilder)override;private:floatmOpacity;boolmForEventsAndPluginsOnly;};classnsDisplayBlendMode:publicnsDisplayWrapList{public:nsDisplayBlendMode(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,uint8_taBlendMode,constActiveScrolledRoot*aActiveScrolledRoot,uint32_taIndex=0);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayBlendMode();#endifnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{// We don't need to compute an invalidation region since we have LayerTreeInvalidation}virtualuint32_tGetPerFrameKey()override{return(mIndex<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualboolTryMerge(nsDisplayItem*aItem)override;virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returnfalse;}NS_DISPLAY_DECL_NAME("BlendMode",TYPE_BLEND_MODE)private:uint8_tmBlendMode;uint32_tmIndex;};classnsDisplayBlendContainer:publicnsDisplayWrapList{public:staticnsDisplayBlendContainer*CreateForMixBlendMode(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot);staticnsDisplayBlendContainer*CreateForBackgroundBlendMode(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayBlendContainer();#endifvirtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolTryMerge(nsDisplayItem*aItem)override;virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returnfalse;}virtualuint32_tGetPerFrameKey()override{return(mIsForBackground?1<<nsDisplayItem::TYPE_BITS:0)|nsDisplayItem::GetPerFrameKey();}NS_DISPLAY_DECL_NAME("BlendContainer",TYPE_BLEND_CONTAINER)private:nsDisplayBlendContainer(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot,boolaIsForBackground);// Used to distinguish containers created at building stacking// context or appending background.boolmIsForBackground;};/** * A display item that has no purpose but to ensure its contents get * their own layer. */classnsDisplayOwnLayer:publicnsDisplayWrapList{public:typedefmozilla::layers::ScrollThumbDataScrollThumbData;/** * nsDisplayOwnLayer constructor flags */enum{GENERATE_SUBDOC_INVALIDATIONS=0x01,VERTICAL_SCROLLBAR=0x02,HORIZONTAL_SCROLLBAR=0x04,GENERATE_SCROLLABLE_LAYER=0x08,SCROLLBAR_CONTAINER=0x10};/** * @param aFlags GENERATE_SUBDOC_INVALIDATIONS : * Add UserData to the created ContainerLayer, so that invalidations * for this layer are send to our nsPresContext. * GENERATE_SCROLLABLE_LAYER : only valid on nsDisplaySubDocument (and * subclasses), indicates this layer is to be a scrollable layer, so call * ComputeFrameMetrics, etc. * @param aScrollTarget when VERTICAL_SCROLLBAR or HORIZONTAL_SCROLLBAR * is set in the flags, this parameter should be the ViewID of the * scrollable content this scrollbar is for. */nsDisplayOwnLayer(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot,uint32_taFlags=0,ViewIDaScrollTarget=mozilla::layers::FrameMetrics::NULL_SCROLL_ID,constScrollThumbData&aThumbData=ScrollThumbData{},boolaForceActive=true);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayOwnLayer();#endifvirtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolTryMerge(nsDisplayItem*aItem)override{// Don't allow merging, each sublist must have its own layerreturnfalse;}virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returnfalse;}uint32_tGetFlags(){returnmFlags;}boolIsScrollThumbLayer()const;NS_DISPLAY_DECL_NAME("OwnLayer",TYPE_OWN_LAYER)protected:uint32_tmFlags;ViewIDmScrollTarget;// If this nsDisplayOwnLayer represents a scroll thumb layer, mThumbData// stores information about the scroll thumb. Otherwise, mThumbData will be// default-constructed (in particular with mDirection == ScrollDirection::NONE)// and can be ignored.ScrollThumbDatamThumbData;boolmForceActive;};/** * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer, * except that it always populates the FrameMetrics instance on the ContainerLayer it * builds. */classnsDisplaySubDocument:publicnsDisplayOwnLayer{public:nsDisplaySubDocument(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,uint32_taFlags);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplaySubDocument();#endifvirtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;NS_DISPLAY_DECL_NAME("SubDocument",TYPE_SUBDOCUMENT)mozilla::UniquePtr<ScrollMetadata>ComputeScrollMetadata(Layer*aLayer,constContainerLayerParameters&aContainerParameters);protected:ViewIDmScrollParentId;boolmForceDispatchToContentRegion;};/** * A display item for subdocuments to capture the resolution from the presShell * and ensure that it gets applied to all the right elements. This item creates * a container layer. */classnsDisplayResolution:publicnsDisplaySubDocument{public:nsDisplayResolution(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,uint32_taFlags);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayResolution();#endifvirtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;NS_DISPLAY_DECL_NAME("Resolution",TYPE_RESOLUTION)};/** * A display item used to represent sticky position elements. The contents * gets its own layer and creates a stacking context, and the layer will have * position-related metadata set on it. */classnsDisplayStickyPosition:publicnsDisplayOwnLayer{public:nsDisplayStickyPosition(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayStickyPosition();#endifvoidSetClipChain(constDisplayItemClipChain*aClipChain)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;NS_DISPLAY_DECL_NAME("StickyPosition",TYPE_STICKY_POSITION)virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override{returnmozilla::LAYER_ACTIVE;}virtualboolTryMerge(nsDisplayItem*aItem)override;};classnsDisplayFixedPosition:publicnsDisplayOwnLayer{public:nsDisplayFixedPosition(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constActiveScrolledRoot*aActiveScrolledRoot);staticnsDisplayFixedPosition*CreateForFixedBackground(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayBackgroundImage*aImage,uint32_taIndex);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayFixedPosition();#endifvirtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;NS_DISPLAY_DECL_NAME("FixedPosition",TYPE_FIXED_POSITION)virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override{returnmozilla::LAYER_ACTIVE_FORCE;}virtualboolTryMerge(nsDisplayItem*aItem)override;virtualboolShouldFixToViewport(nsDisplayListBuilder*aBuilder)override{returnmIsFixedBackground;}virtualuint32_tGetPerFrameKey()override{return(mIndex<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}AnimatedGeometryRoot*AnimatedGeometryRootForScrollMetadata()constoverride{returnmAnimatedGeometryRootForScrollMetadata;}protected:// For background-attachment:fixednsDisplayFixedPosition(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,uint32_taIndex);voidInit(nsDisplayListBuilder*aBuilder);AnimatedGeometryRoot*mAnimatedGeometryRootForScrollMetadata;uint32_tmIndex;boolmIsFixedBackground;};classnsDisplayTableFixedPosition:publicnsDisplayFixedPosition{public:staticnsDisplayTableFixedPosition*CreateForFixedBackground(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayBackgroundImage*aImage,uint32_taIndex,nsIFrame*aAncestorFrame);virtualuint32_tGetPerFrameKey()override{return(mIndex<<(nsDisplayItem::TYPE_BITS+static_cast<uint8_t>(TableTypeBits::COUNT)))|(static_cast<uint8_t>(mTableType)<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}protected:nsDisplayTableFixedPosition(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,uint32_taIndex,nsIFrame*aAncestorFrame);TableTypemTableType;};/** * This creates an empty scrollable layer. It has no child layers. * It is used to record the existence of a scrollable frame in the layer * tree. */classnsDisplayScrollInfoLayer:publicnsDisplayWrapList{public:nsDisplayScrollInfoLayer(nsDisplayListBuilder*aBuilder,nsIFrame*aScrolledFrame,nsIFrame*aScrollFrame);NS_DISPLAY_DECL_NAME("ScrollInfoLayer",TYPE_SCROLL_INFO_LAYER)#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayScrollInfoLayer();#endifvirtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder)override{returntrue;}virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=false;returnnsRegion();}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returnfalse;}virtualvoidWriteDebugInfo(std::stringstream&aStream)override;mozilla::UniquePtr<ScrollMetadata>ComputeScrollMetadata(Layer*aLayer,constContainerLayerParameters&aContainerParameters);protected:nsIFrame*mScrollFrame;nsIFrame*mScrolledFrame;ViewIDmScrollParentId;};/** * nsDisplayZoom is used for subdocuments that have a different full zoom than * their parent documents. This item creates a container layer. */classnsDisplayZoom:publicnsDisplaySubDocument{public:/** * @param aFrame is the root frame of the subdocument. * @param aList contains the display items for the subdocument. * @param aAPD is the app units per dev pixel ratio of the subdocument. * @param aParentAPD is the app units per dev pixel ratio of the parent * document. * @param aFlags GENERATE_SUBDOC_INVALIDATIONS : * Add UserData to the created ContainerLayer, so that invalidations * for this layer are send to our nsPresContext. */nsDisplayZoom(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,int32_taAPD,int32_taParentAPD,uint32_taFlags=0);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayZoom();#endifvirtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override{returnmozilla::LAYER_ACTIVE;}NS_DISPLAY_DECL_NAME("Zoom",TYPE_ZOOM)// Get the app units per dev pixel ratio of the child document.int32_tGetChildAppUnitsPerDevPixel(){returnmAPD;}// Get the app units per dev pixel ratio of the parent document.int32_tGetParentAppUnitsPerDevPixel(){returnmParentAPD;}private:int32_tmAPD,mParentAPD;};classnsDisplaySVGEffects:publicnsDisplayWrapList{public:nsDisplaySVGEffects(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,boolaHandleOpacity,constActiveScrolledRoot*aActiveScrolledRoot);nsDisplaySVGEffects(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,boolaHandleOpacity);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplaySVGEffects();#endifvirtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualboolShouldFlattenAway(nsDisplayListBuilder*aBuilder)override{returnfalse;}gfxRectBBoxInUserSpace()const;gfxPointUserSpaceOffset()const;virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;protected:boolValidateSVGFrame();// relative to mFramensRectmEffectsBounds;// True if we need to handle css opacity in this display item.boolmHandleOpacity;};/** * A display item to paint a stacking context with mask and clip effects * set by the stacking context root frame's style. */classnsDisplayMask:publicnsDisplaySVGEffects{public:typedefmozilla::layers::ImageLayerImageLayer;nsDisplayMask(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,boolaHandleOpacity,constActiveScrolledRoot*aActiveScrolledRoot);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayMask();#endifNS_DISPLAY_DECL_NAME("Mask",TYPE_MASK)virtualboolTryMerge(nsDisplayItem*aItem)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayMaskGeometry(this,aBuilder);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;#ifdef MOZ_DUMP_PAINTINGvoidPrintEffects(nsACString&aTo);#endifvoidPaintAsLayer(nsDisplayListBuilder*aBuilder,gfxContext*aCtx,LayerManager*aManager);/* * Paint mask onto aMaskContext in mFrame's coordinate space and * return whether the mask layer was painted successfully. */boolPaintMask(nsDisplayListBuilder*aBuilder,gfxContext*aMaskContext);constnsTArray<nsRect>&GetDestRects(){returnmDestRects;}private:// According to mask property and the capability of aManager, determine// whether paint mask onto a dedicate mask layer.boolShouldPaintOnMaskLayer(LayerManager*aManager);nsTArray<nsRect>mDestRects;};/** * A display item to paint a stacking context with filter effects set by the * stacking context root frame's style. */classnsDisplayFilter:publicnsDisplaySVGEffects{public:nsDisplayFilter(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,boolaHandleOpacity);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayFilter();#endifNS_DISPLAY_DECL_NAME("Filter",TYPE_FILTER)virtualboolTryMerge(nsDisplayItem*aItem)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{*aSnap=false;returnmEffectsBounds+ToReferenceFrame();}virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override{returnnewnsDisplayFilterGeometry(this,aBuilder);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;#ifdef MOZ_DUMP_PAINTINGvoidPrintEffects(nsACString&aTo);#endifvoidPaintAsLayer(nsDisplayListBuilder*aBuilder,gfxContext*aCtx,LayerManager*aManager);};/* A display item that applies a transformation to all of its descendant * elements. This wrapper should only be used if there is a transform applied * to the root element. * * The reason that a "bounds" rect is involved in transform calculations is * because CSS-transforms allow percentage values for the x and y components * of <translation-value>s, where percentages are percentages of the element's * border box. * * INVARIANT: The wrapped frame is transformed or we supplied a transform getter * function. * INVARIANT: The wrapped frame is non-null. */classnsDisplayTransform:publicnsDisplayItem{typedefmozilla::gfx::Matrix4x4Matrix4x4;typedefmozilla::gfx::Point3DPoint3D;/* * Avoid doing UpdateBounds() during construction. */classStoreList:publicnsDisplayWrapList{public:StoreList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList):nsDisplayWrapList(aBuilder,aFrame,aList){}StoreList(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayItem*aItem):nsDisplayWrapList(aBuilder,aFrame,aItem){}virtual~StoreList(){}virtualvoidUpdateBounds(nsDisplayListBuilder*aBuilder)override{// For extending 3d rendering context, the bounds would be// updated by DoUpdateBoundsPreserves3D(), not here.if(!mFrame->Extend3DContext()){nsDisplayWrapList::UpdateBounds(aBuilder);}}virtualvoidDoUpdateBoundsPreserves3D(nsDisplayListBuilder*aBuilder)override{for(nsDisplayItem*i=mList.GetBottom();i;i=i->GetAbove()){i->DoUpdateBoundsPreserves3D(aBuilder);}nsDisplayWrapList::UpdateBounds(aBuilder);}};public:enumPrerenderDecision{NoPrerender,FullPrerender,PartialPrerender};/** * Returns a matrix (in pixels) for the current frame. The matrix should be relative to * the current frame's coordinate space. * * @param aFrame The frame to compute the transform for. * @param aAppUnitsPerPixel The number of app units per graphics unit. */typedefMatrix4x4(*ComputeTransformFunction)(nsIFrame*aFrame,floataAppUnitsPerPixel);/* Constructor accepts a display list, empties it, and wraps it up. It also * ferries the underlying frame to the nsDisplayItem constructor. */nsDisplayTransform(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constnsRect&aChildrenVisibleRect,uint32_taIndex=0,boolaAllowAsyncAnimation=false);nsDisplayTransform(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayItem*aItem,constnsRect&aChildrenVisibleRect,uint32_taIndex=0);nsDisplayTransform(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constnsRect&aChildrenVisibleRect,ComputeTransformFunctionaTransformGetter,uint32_taIndex=0);nsDisplayTransform(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsDisplayList*aList,constnsRect&aChildrenVisibleRect,constMatrix4x4&aTransform,uint32_taIndex=0);#ifdef NS_BUILD_REFCNT_LOGGINGvirtual~nsDisplayTransform(){MOZ_COUNT_DTOR(nsDisplayTransform);}#endifNS_DISPLAY_DECL_NAME("nsDisplayTransform",TYPE_TRANSFORM)virtualnsRectGetComponentAlphaBounds(nsDisplayListBuilder*aBuilder)override{if(mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())returnnsRect();boolsnap;returnGetBounds(aBuilder,&snap);}virtualnsDisplayList*GetChildren()override{returnmStoredList.GetChildren();}virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override;virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override;virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override;virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolCreateWebRenderCommands(mozilla::wr::DisplayListBuilder&aBuilder,constStackingContextHelper&aSc,nsTArray<WebRenderParentCommand>&aParentCommands,mozilla::layers::WebRenderLayerManager*aManager,nsDisplayListBuilder*aDisplayListBuilder)override;virtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override;virtualboolTryMerge(nsDisplayItem*aItem)override;virtualuint32_tGetPerFrameKey()override{return(mIndex<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{// We don't need to compute an invalidation region since we have LayerTreeInvalidation}virtualconstnsIFrame*ReferenceFrameForChildren()constoverride{// If we were created using a transform-getter, then we don't// belong to a transformed frame, and aren't a reference frame// for our children.if(!mTransformGetter){returnmFrame;}returnnsDisplayItem::ReferenceFrameForChildren();}AnimatedGeometryRoot*AnimatedGeometryRootForScrollMetadata()constoverride{returnmAnimatedGeometryRootForScrollMetadata;}virtualconstnsRect&GetVisibleRectForChildren()constoverride{returnmChildrenVisibleRect;}enum{INDEX_MAX=UINT32_MAX>>nsDisplayItem::TYPE_BITS};/** * We include the perspective matrix from our containing block for the * purposes of visibility calculations, but we exclude it from the transform * we set on the layer (for rendering), since there will be an * nsDisplayPerspective created for that. */constMatrix4x4&GetTransform();Matrix4x4GetTransformForRendering();/** * Return the transform that is aggregation of all transform on the * preserves3d chain. */constMatrix4x4&GetAccumulatedPreserved3DTransform(nsDisplayListBuilder*aBuilder);floatGetHitDepthAtPoint(nsDisplayListBuilder*aBuilder,constnsPoint&aPoint);/** * TransformRect takes in as parameters a rectangle (in aFrame's coordinate * space) and returns the smallest rectangle (in aFrame's coordinate space) * containing the transformed image of that rectangle. That is, it takes * the four corners of the rectangle, transforms them according to the * matrix associated with the specified frame, then returns the smallest * rectangle containing the four transformed points. * * @param untransformedBounds The rectangle (in app units) to transform. * @param aFrame The frame whose transformation should be applied. This * function raises an assertion if aFrame is null or doesn't have a * transform applied to it. * @param aOrigin The origin of the transform relative to aFrame's local * coordinate space. * @param aBoundsOverride (optional) Rather than using the frame's computed * bounding rect as frame bounds, use this rectangle instead. Pass * nullptr (or nothing at all) to use the default. */staticnsRectTransformRect(constnsRect&aUntransformedBounds,constnsIFrame*aFrame,constnsRect*aBoundsOverride=nullptr);/* UntransformRect is like TransformRect, except that it inverts the * transform. */staticboolUntransformRect(constnsRect&aTransformedBounds,constnsRect&aChildBounds,constnsIFrame*aFrame,nsRect*aOutRect);boolUntransformVisibleRect(nsDisplayListBuilder*aBuilder,nsRect*aOutRect);staticPoint3DGetDeltaToTransformOrigin(constnsIFrame*aFrame,floataAppUnitsPerPixel,constnsRect*aBoundsOverride);/* * Returns true if aFrame has perspective applied from its containing * block. * Returns the matrix to append to apply the persective (taking * perspective-origin into account), relative to aFrames coordinate * space). * aOutMatrix is assumed to be the identity matrix, and isn't explicitly * cleared. */staticboolComputePerspectiveMatrix(constnsIFrame*aFrame,floataAppUnitsPerPixel,Matrix4x4&aOutMatrix);structFrameTransformProperties{FrameTransformProperties(constnsIFrame*aFrame,floataAppUnitsPerPixel,constnsRect*aBoundsOverride);FrameTransformProperties(nsCSSValueSharedList*aTransformList,constPoint3D&aToTransformOrigin):mFrame(nullptr),mTransformList(aTransformList),mToTransformOrigin(aToTransformOrigin){}constnsIFrame*mFrame;RefPtr<nsCSSValueSharedList>mTransformList;constPoint3DmToTransformOrigin;};/** * Given a frame with the -moz-transform property or an SVG transform, * returns the transformation matrix for that frame. * * @param aFrame The frame to get the matrix from. * @param aOrigin Relative to which point this transform should be applied. * @param aAppUnitsPerPixel The number of app units per graphics unit. * @param aBoundsOverride [optional] If this is nullptr (the default), the * computation will use the value of TransformReferenceBox(aFrame). * Otherwise, it will use the value of aBoundsOverride. This is * mostly for internal use and in most cases you will not need to * specify a value. * @param aFlags OFFSET_BY_ORIGIN The resulting matrix will be translated * by aOrigin. This translation is applied *before* the CSS transform. * @param aFlags INCLUDE_PRESERVE3D_ANCESTORS The computed transform will * include the transform of any ancestors participating in the same * 3d rendering context. * @param aFlags INCLUDE_PERSPECTIVE The resulting matrix will include the * perspective transform from the containing block if applicable. */enum{OFFSET_BY_ORIGIN=1<<0,INCLUDE_PRESERVE3D_ANCESTORS=1<<1,INCLUDE_PERSPECTIVE=1<<2,};staticMatrix4x4GetResultingTransformMatrix(constnsIFrame*aFrame,constnsPoint&aOrigin,floataAppUnitsPerPixel,uint32_taFlags,constnsRect*aBoundsOverride=nullptr);staticMatrix4x4GetResultingTransformMatrix(constFrameTransformProperties&aProperties,constnsPoint&aOrigin,floataAppUnitsPerPixel,uint32_taFlags,constnsRect*aBoundsOverride=nullptr);/** * Decide whether we should prerender some or all of the contents of the * transformed frame even when it's not completely visible (yet). * Return FullPrerender if the entire contents should be prerendered, * PartialPrerender if some but not all of the contents should be prerendered, * or NoPrerender if only the visible area should be rendered. * |aDirtyRect| is updated to the area that should be prerendered. */staticPrerenderDecisionShouldPrerenderTransformedContent(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame,nsRect*aDirtyRect);boolCanUseAsyncAnimations(nsDisplayListBuilder*aBuilder)override;boolMayBeAnimated(nsDisplayListBuilder*aBuilder);virtualvoidWriteDebugInfo(std::stringstream&aStream)override;// Force the layer created for this item not to extend 3D context.// See nsIFrame::BuildDisplayListForStackingContext()voidSetNoExtendContext(){mNoExtendContext=true;}virtualvoidDoUpdateBoundsPreserves3D(nsDisplayListBuilder*aBuilder)override{MOZ_ASSERT(mFrame->Combines3DTransformWithAncestors()||IsTransformSeparator());// Updating is not going through to child 3D context.ComputeBounds(aBuilder);}/** * This function updates bounds for items with a frame establishing * 3D rendering context. * * \see nsDisplayItem::DoUpdateBoundsPreserves3D() */voidUpdateBoundsFor3D(nsDisplayListBuilder*aBuilder){if(!mFrame->Extend3DContext()||mFrame->Combines3DTransformWithAncestors()||IsTransformSeparator()){// Not an establisher of a 3D rendering context.return;}// Always start updating from an establisher of a 3D rendering context.nsDisplayListBuilder::AutoAccumulateRectaccRect(aBuilder);nsDisplayListBuilder::AutoAccumulateTransformaccTransform(aBuilder);accTransform.StartRoot();ComputeBounds(aBuilder);mBounds=aBuilder->GetAccumulatedRect();mHasBounds=true;}/** * This item is an additional item as the boundary between parent * and child 3D rendering context. * \see nsIFrame::BuildDisplayListForStackingContext(). */boolIsTransformSeparator(){returnmIsTransformSeparator;}/** * This item is the boundary between parent and child 3D rendering * context. */boolIsLeafOf3DContext(){return(IsTransformSeparator()||(!mFrame->Extend3DContext()&&mFrame->Combines3DTransformWithAncestors()));}/** * The backing frame of this item participates a 3D rendering * context. */boolIsParticipating3DContext(){returnmFrame->Extend3DContext()||mFrame->Combines3DTransformWithAncestors();}private:voidComputeBounds(nsDisplayListBuilder*aBuilder);voidSetReferenceFrameToAncestor(nsDisplayListBuilder*aBuilder);voidInit(nsDisplayListBuilder*aBuilder);staticMatrix4x4GetResultingTransformMatrixInternal(constFrameTransformProperties&aProperties,constnsPoint&aOrigin,floataAppUnitsPerPixel,uint32_taFlags,constnsRect*aBoundsOverride);StoreListmStoredList;Matrix4x4mTransform;// Accumulated transform of ancestors on the preserves-3d chain.Matrix4x4mTransformPreserves3D;ComputeTransformFunctionmTransformGetter;AnimatedGeometryRoot*mAnimatedGeometryRootForChildren;AnimatedGeometryRoot*mAnimatedGeometryRootForScrollMetadata;nsRectmChildrenVisibleRect;uint32_tmIndex;nsRectmBounds;// True for mBounds is valid.boolmHasBounds;// Be forced not to extend 3D context. Since we don't create a// transform item, a container layer, for every frames in a// preserves3d context, the transform items of a child preserves3d// context may extend the parent context not intented if the root of// the child preserves3d context doesn't create a transform item.// With this flags, we force the item not extending 3D context.boolmNoExtendContext;// This item is a separator between 3D rendering contexts, and// mTransform have been presetted by the constructor.boolmIsTransformSeparator;// True if mTransformPreserves3D have been initialized.boolmTransformPreserves3DInited;// True if async animation of the transform is allowed.boolmAllowAsyncAnimation;};/* A display item that applies a perspective transformation to a single * nsDisplayTransform child item. We keep this as a separate item since the * perspective-origin is relative to an ancestor of the transformed frame, and * APZ can scroll the child separately. */classnsDisplayPerspective:publicnsDisplayItem{typedefmozilla::gfx::Point3DPoint3D;public:NS_DISPLAY_DECL_NAME("nsDisplayPerspective",TYPE_PERSPECTIVE)nsDisplayPerspective(nsDisplayListBuilder*aBuilder,nsIFrame*aTransformFrame,nsIFrame*aPerspectiveFrame,nsDisplayList*aList);virtualuint32_tGetPerFrameKey()override{return(mIndex<<nsDisplayItem::TYPE_BITS)|nsDisplayItem::GetPerFrameKey();}virtualvoidHitTest(nsDisplayListBuilder*aBuilder,constnsRect&aRect,HitTestState*aState,nsTArray<nsIFrame*>*aOutFrames)override{returnmList.HitTest(aBuilder,aRect,aState,aOutFrames);}virtualnsRectGetBounds(nsDisplayListBuilder*aBuilder,bool*aSnap)override{returnmList.GetBounds(aBuilder,aSnap);}virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override{}virtualnsRegionGetOpaqueRegion(nsDisplayListBuilder*aBuilder,bool*aSnap)override{returnmList.GetOpaqueRegion(aBuilder,aSnap);}virtualmozilla::Maybe<nscolor>IsUniform(nsDisplayListBuilder*aBuilder)override{returnmList.IsUniform(aBuilder);}virtualLayerStateGetLayerState(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aParameters)override;virtualboolShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder*aBuilder)override{if(!mList.GetChildren()->GetTop()){returnfalse;}returnmList.GetChildren()->GetTop()->ShouldBuildLayerEvenIfInvisible(aBuilder);}virtualalready_AddRefed<Layer>BuildLayer(nsDisplayListBuilder*aBuilder,LayerManager*aManager,constContainerLayerParameters&aContainerParameters)override;virtualboolComputeVisibility(nsDisplayListBuilder*aBuilder,nsRegion*aVisibleRegion)override{mList.RecomputeVisibility(aBuilder,aVisibleRegion);returntrue;}virtualnsDisplayList*GetSameCoordinateSystemChildren()override{returnmList.GetChildren();}virtualnsDisplayList*GetChildren()override{returnmList.GetChildren();}virtualnsRectGetComponentAlphaBounds(nsDisplayListBuilder*aBuilder)override{returnmList.GetComponentAlphaBounds(aBuilder);}nsIFrame*TransformFrame(){returnmTransformFrame;}virtualint32_tZIndex()constoverride;virtualvoidDoUpdateBoundsPreserves3D(nsDisplayListBuilder*aBuilder)override{if(mList.GetChildren()->GetTop()){static_cast<nsDisplayTransform*>(mList.GetChildren()->GetTop())->DoUpdateBoundsPreserves3D(aBuilder);}}private:nsDisplayWrapListmList;nsIFrame*mTransformFrame;uint32_tmIndex;};/** * This class adds basic support for limiting the rendering (in the inline axis * of the writing mode) to the part inside the specified edges. It's a base * class for the display item classes that do the actual work. * The two members, mVisIStartEdge and mVisIEndEdge, are relative to the edges * of the frame's scrollable overflow rectangle and are the amount to suppress * on each side. * * Setting none, both or only one edge is allowed. * The values must be non-negative. * The default value for both edges is zero, which means everything is painted. */classnsCharClipDisplayItem:publicnsDisplayItem{public:nsCharClipDisplayItem(nsDisplayListBuilder*aBuilder,nsIFrame*aFrame):nsDisplayItem(aBuilder,aFrame),mVisIStartEdge(0),mVisIEndEdge(0){}explicitnsCharClipDisplayItem(nsIFrame*aFrame):nsDisplayItem(aFrame){}virtualnsDisplayItemGeometry*AllocateGeometry(nsDisplayListBuilder*aBuilder)override;virtualvoidComputeInvalidationRegion(nsDisplayListBuilder*aBuilder,constnsDisplayItemGeometry*aGeometry,nsRegion*aInvalidRegion)override;structClipEdges{ClipEdges(constnsDisplayItem&aItem,nscoordaVisIStartEdge,nscoordaVisIEndEdge){nsRectr=aItem.Frame()->GetScrollableOverflowRect()+aItem.ToReferenceFrame();if(aItem.Frame()->GetWritingMode().IsVertical()){mVisIStart=aVisIStartEdge>0?r.y+aVisIStartEdge:nscoord_MIN;mVisIEnd=aVisIEndEdge>0?std::max(r.YMost()-aVisIEndEdge,mVisIStart):nscoord_MAX;}else{mVisIStart=aVisIStartEdge>0?r.x+aVisIStartEdge:nscoord_MIN;mVisIEnd=aVisIEndEdge>0?std::max(r.XMost()-aVisIEndEdge,mVisIStart):nscoord_MAX;}}voidIntersect(nscoord*aVisIStart,nscoord*aVisISize)const{nscoordend=*aVisIStart+*aVisISize;*aVisIStart=std::max(*aVisIStart,mVisIStart);*aVisISize=std::max(std::min(end,mVisIEnd)-*aVisIStart,0);}nscoordmVisIStart;nscoordmVisIEnd;};ClipEdgesEdges()const{returnClipEdges(*this,mVisIStartEdge,mVisIEndEdge);}staticnsCharClipDisplayItem*CheckCast(nsDisplayItem*aItem){nsDisplayItem::Typet=aItem->GetType();return(t==nsDisplayItem::TYPE_TEXT)?static_cast<nsCharClipDisplayItem*>(aItem):nullptr;}// Lengths measured from the visual inline start and end sides// (i.e. left and right respectively in horizontal writing modes,// regardless of bidi directionality; top and bottom in vertical modes).nscoordmVisIStartEdge;nscoordmVisIEndEdge;// Cached result of mFrame->IsSelected(). Only initialized when needed.mutablemozilla::Maybe<bool>mIsFrameSelected;};namespacemozilla{classPaintTelemetry{public:enumclassMetric{DisplayList,Layerization,Rasterization,COUNT,};classAutoRecord{public:explicitAutoRecord(MetricaMetric);~AutoRecord();TimeStampGetStart()const{returnmStart;}private:MetricmMetric;mozilla::TimeStampmStart;};classAutoRecordPaint{public:AutoRecordPaint();~AutoRecordPaint();private:mozilla::TimeStampmStart;};private:staticuint32_tsPaintLevel;staticuint32_tsMetricLevel;staticmozilla::EnumeratedArray<Metric,Metric::COUNT,double>sMetrics;};}// namespace mozilla#endif /*NSDISPLAYLIST_H_*/